基礎算法3_選擇排序(簡單選擇排序+堆排序)

基本思想:選擇排序 顧名思義就是要進行選擇,如對9 6 11 7 進行排序,第一趟排序從這四個數中選出最小的數7 排在第一個 接下來就從剩餘的三個數中選擇最小的一個 那麼選擇排序基本就是這個思想。

1.簡單選擇排序(直接看代碼)

	//核心算法
	//A是待排序數組 n是表長
	public void SelectSort(int[] A,int n ){
		int i,j,min;//min用於在待排序元素中找到最小位置的元素
		//最後一個元素不用選擇了
		for(i=0;i<n-1;i++){
			min=i;
			for(j=i+1;j<n;j++){
				if(A[j]<A[min]) 
					min=j;//找最小元素位置
			}
			//交換位置(想想冒泡排序的交換)
			if (min!=i) {
				int temp=A[i];
				A[i]=A[min];
				A[min]=temp;
			}
		}
	}

2.堆排序(在交換排序中是比較重要的一種算法了 是一種樹形排序結構)

堆分爲大頂堆和小頂堆,以大頂堆爲例,大頂堆可以看成是一棵完全二叉樹的結構,大頂堆的堆頂比起左子樹和右子樹的數都大,因此我們要理解好大頂堆就首先要理解什麼是二叉樹?進一步理解什麼是排序二叉樹?什麼是完全二叉樹?

二叉樹:就是其分支最多爲2的樹 如以下四種情況

  

排序二叉樹:A結點的左子樹所有數都比A小,A結點的右子樹所有數都比A大

完全二叉樹:看一個圖來理解

(百度上的)完全二叉樹是效率很高的數據結構,完全二叉樹是由滿二叉樹而引出來的。對於深度爲K的,有n個結點的二叉樹,當且僅當其每一個結點都與深度爲K的滿二叉樹中編號從1至n的結點一一對應時稱之爲完全二叉樹。

在簡單回顧了這些內容後,就是來了解堆排序了,

1》. 構造一個初始堆(n=5)

2》進行反覆篩選調整 建立大頂堆(核心就在此)

     2.1從有孩子的結點開始從後向前進行調整。由完全二叉樹的性質,二叉樹的最後一個有孩子結點是n/2(向下取整)

再舉個例子 進一步鞏固

所以堆排序的核心就在於將有孩子的結點與其左右孩子進行比較 交換 再不斷進行調整

看代碼:

public class Sort7 {
	//建立大根堆
	public void BuildMaxHeap(int A[],int n){
		//從有孩子的結點開始從後向前進行調整
		for(int i=n/2;i>0;i--){
			adjustDown(A,i,n);
		}
	}
	//核心算法
	public void adjustDown(int A[],int k,int n){
		int i,j;
		//將k處結點向下調整 A[0]元素用於暫存
		A[0]=A[k];
		for(i=2*k;i<=n;i=i*2){
			//1.找出k結點左右孩子的最大值 左孩子結點位置數爲偶數 右孩子爲奇數
			if(i<n&&A[i]<A[i+1]){
				//右孩子大於左孩子
				i++;
			}
			//2.將k結點和左右孩子中的最大值進行比較
			    //2.1 若k結點大於其最大值 不交換 本次篩選結束 進行下一個節點的調整
			if(A[i]<=A[0]) break;
			else{
				//2.2若k結點小於其最大值進行交換
				A[k]=A[i];//交換
				k=i;//交換後可能會破壞大頂堆 所以進行向下調整
			}
		}
		//3.將k結點放在最終位置上
		A[k]=A[0];	
	}
	
	//快速排序
	void HeapSort(int A[],int n){
		BuildMaxHeap(A, n);//建堆
		for(int i=n;i>1;i--){
			//將大頂堆的堆頂元素輸出:先將堆頂元素與最後一個元素交換,然後再調整大頂堆
			int temp=A[1];
			A[1]=A[i];
			A[i]=temp;
			adjustDown(A, 1, i-1);
		}
		
		
	}
	//A是待排序數組 n是表長
	public void insertSort(int[] A,int n ){
		int i,j;
		for(i=2;i<=n;i++){
			//待插入的數據A[i]大於A[i-1],則直接插入,反之則往前進行比較,
			//選擇合適的插入的位置
			if(A[i]<A[i-1]){
				//A[0]僅是哨兵
				A[0]=A[i];
				//邊查找邊移動位置
				for(j=i-1;A[i]<A[j];j--){
					A[j+1]=A[j];
				}
				//找到插入位置
				A[j+1]=A[0];
			}
		}
	}

	//測試
    public static void main(String[] args) {
    	int[] A={0,2,12,6,8,11,31,18,27};
    	int n =A.length-1;
    	InsertSort7 insertSort = new InsertSort7();
    	insertSort.HeapSort(A, n);
    	for(int i=0;i<=n;i++){
    		System.out.println(A[i]);
    	}
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章