1. 程式人生 > >常見的8大排序演算法和查詢演算法

常見的8大排序演算法和查詢演算法

假設所有陣列要求的結果都要為升序
基本上的迴圈退出條件要考慮0的情況,因為很可能會造成死迴圈:if start<=end 如果start,end不是跳躍式的,很可能一直為start=0,end=0 從而造成死迴圈
1.直接插入排序:
核心:長度為n的陣列,假設n-1都是有序的,則只需要插入即可

	public static void simpleInsert(Integer[] arr)
	{
		for (int i = 0; i < arr.length; i++)
		{
			int temp = arr[i];
			int j = i - 1;
			for (; j >=0 && arr[j] > temp; j--)
				// 滿足條件(既:大於則這個元素後移)
				arr[j + 1] = arr[j];
			// 插入元素
			arr[j + 1] = temp;
		}
	}

2.希爾排序:是直接插入排序的優化版,採用步長來分組,對每個分組進行直接插入排序

public static void sheelSort(Integer[] arr)
	{
		int stride = arr.length;
		while (stride != 1)
		{
			stride >>= 1;
			// 對每個分組進行直接排序
			for (int i = 0; i < stride; i++)
			{
				for (int j = 0; j < arr.length; j += stride)
				{
					int temp = arr[j];
					int k = j - stride;
					for (; k >= 0 && arr[k] > temp; k -= stride)
						// 後移
						arr[k + stride] = arr[k];
					// 插入
					arr[k + stride] = temp;
				}
			}
		}
	}

其實直接插入排序就是與步長為1的希爾排序差不多

3.簡單選擇排序:
核心:將最小的交換到0出,第二小的交換到1出,依次繼續(意味著需要更換陣列小標,同時也就意味著需要儲存位置)

public static void selectionSort(Integer[] arr)
	{
		// 對陣列下標進行一一賦值
		for (int i = 0; i < arr.length; i++)
		{
			int min=arr[i];
			int pos=i;
			for(int j=i+1;j<arr.length;j++)
			{
				if(arr[j]<min)
				{
				//儲存最小的
					min=arr[j];
					pos=j;
				}
			}
			//與下標對應的交換
			arr[pos]=arr[i];
			arr[i]=min;
		}
	}

4.堆排序:是簡單選擇排序的優化
核心:堆的特性,分2個過程 建堆->排序

public static void buildHeap(Integer[] arr)
	{
		for (int i = (arr.length >> 1) - 1; i >= 0; i--)
		{
			doBuildMaxHeap(arr, i, arr.length);
		}
		ArrayCommon.show(arr);
	}

	public static void doBuildMaxHeap(Integer[] arr, int start, int limit)
	{
		int left = getLeftChildIndex(start);
		int right = getRightChildIndex(start);
		int maxIndex = start;
		if (left < limit && arr[left] > arr[maxIndex])
			maxIndex = left;
		if (right < limit && arr[right] > arr[maxIndex])
			maxIndex = right;
		//說明左右節點都比根節點小,那啥也不用幹了
		if(maxIndex==start) return;
		//交換位置
		int temp=arr[start];
		arr[start]=arr[maxIndex];
		arr[maxIndex]=temp;
		//遞迴重新構建堆
		doBuildMaxHeap(arr, maxIndex, limit);
	}

	public static int getLeftChildIndex(int i)
	{
		return ((i + 1) << 1) - 1;
	}

	public static int getRightChildIndex(int i)
	{
		return (i + 1) << 1;
	}
	public static void sort(Integer[] arr )
	{
		for(int i=arr.length-1;i>0;i--)
		{
			//將最大的放到最後
			int temp=arr[0];
			arr[0]=arr[i];
			arr[i]=temp;
			//對剩餘的重新構建堆
			doBuildMaxHeap(arr, 0, i);
		}
	}