排序1 O(nlogn)

nlogn的排序:堆排,快排,歸併 

堆排序(英語:Heapsort)是指利用這種數據結構所設計的一種排序算法。堆是一個近似完全二叉樹的結構,並同時滿足堆積的性質:即子結點的鍵值或索引總是小於(或者大於)它的父節點。 

	void adjustHeap(int a[], int i, int size)
	{
		//int max;
		int l = 2 * i + 1;
		int r = 2 * i + 2;
		int max = i;
		//vs 2017 會檢測&&右邊的,故不能將l < size&& a[l] > a[max]書寫
		if (l < size) {
			if ( a[l] > a[max])
				max = l;
		}
		if (r < size) {
			if ( a[r] > a[max])
				max = r;
		}
		if (max != i)
		{
			::std::swap(a[i], a[max]);
			adjustHeap(a, max, size);
		}
	}

	void heapSort(int a[],int size)
	{
		for (int i = size / 2 - 1; i >=0; i--)
		{
			adjustHeap(a, i, size);
		}
		for (int i = size-1;i >= 0; i--)
		{
			swap(a[0], a[i]);
			adjustHeap(a, 0, i);
		}
	}

冒泡排序(Bubble Sort),是一種計算機科學領域的較簡單的排序算法

它重複地走訪過要排序的元素列,依次比較兩個相鄰的元素,如果他們的順序(如從大到小、首字母從A到Z)錯誤就把他們交換過來。走訪元素的工作是重複地進行直到沒有相鄰元素需要交換,也就是說該元素列已經排序完成。

這個算法的名字由來是因爲越大的元素會經由交換慢慢“浮”到數列的頂端(升序或降序排列),就如同碳酸飲料中二氧化碳的氣泡最終會上浮到頂端一樣,故名“冒泡排序”。

 

	void bubbleSort(int a[], int size)
	{
		for (int i = 0; i < size - 1; i++)
		{
			for (int j = 0; j < size - i - 1; j++)
			{
				if (a[j] > a[j + 1])
					::std::swap(a[j + 1], a[j]);
			}
		}
	}

快速排序(Quicksort):通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列

快速排序(Quicksort)是對冒泡排序的一種改進。

 

 

	int quickSortPart(int a[],int left,int right)
	{
		int temp = a[right];
		while (left<right)
		{
			while (left<right&&a[left]<temp )
			{
				left++;
			}
			a[right] = a[left];
			while (left < right&&a[right] >=temp)
			{
				right--;
			}
			a[left] = a[right];
		}
		a[right] = temp;
		return right;
	}
	void quickSort(int a[], int left, int right)
	{
		if (left<right)
		{
			int mid = quickSortPart(a, left, right);
			quickSort(a, left, mid - 1);
			quickSort(a, mid + 1, right);
		}
	}

 歸併排序(MERGE-SORT)是建立在歸併操作上的一種有效的排序算法,該算法是採用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱爲二路歸併

void MergeData(int* arr, int left, int mid, int right, int* tmp) {
		int index = left;
		int p = left, q = mid;	 // 雙指針遍歷
		// 待排區間===[left , right)
		// 左有序區間[left, mid)         右有序區間[mid, right) 
		while (p < mid && q < right) {
			if (arr[p] <= arr[q]) {
				tmp[index++] = arr[p++];
			}
			else {
				tmp[index++] = arr[q++];
			}
		}
		while (p < mid) {
			tmp[index++] = arr[p++];
		}
		while (q < right) {
			tmp[index++] = arr[q++];
		}
		for (int i = left; i < right; i++) {
			// [left, right)內的數列已全部有序
			arr[i] = tmp[i];
		}
	}
	void _MergeSort(int* arr, int left, int right, int* tmp) {
		if (right - left > 1) {
			int mid = left + ((right - left) >> 1);
			// 1.排左區間
			_MergeSort(arr, left, mid, tmp);
			// 2.排右區間
			_MergeSort(arr, mid, right, tmp);
			// 3.歸併
			MergeData(arr, left, mid, right, tmp);
		}
	}
	void MergeSort(int* arr, int size) {
		int* tmp = (int*)malloc(sizeof(int) * size);
		if (tmp == NULL) {
			cout<<"error"<<endl;
			return;
		}
		_MergeSort(arr, 0, size, tmp);
		free(tmp);
	}

 

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