排序(全)

来源:互联网 发布:淘宝 一千零一夜 编辑:程序博客网 时间:2024/04/30 06:44

非比较排序:计数排序,基数排序


直接插入排序

“test.cpp”

#include<iostream>using namespace std;#include<assert.h>void InsertSort(int* arr,size_t size){assert(arr);for(int i = 0;i < size-1;i++){int j = i;int tmp = arr[i+1];while(j >= 0 && arr[j] > tmp){arr[j+1] = arr[j];j--;}arr[j+1] = tmp;}}void test(){int arr[] = {3,7,1,0,2,6,8,5,9,4};size_t size = sizeof(arr)/sizeof(arr[0]);InsertSort(arr,size);for(size_t i = 0;i < size;i++){cout<<arr[i]<<" ";}cout<<endl;}int main(){test();return 0;}


希尔排序

“test.cpp”

#include<iostream>using namespace std;#include<assert.h>void ShellSort(int* arr,size_t size){assert(arr);int gap = size;while(gap > 1){gap = gap / 3 + 1;for(int i = 0;i < size - gap;i++){int j = i;int tmp = arr[i+gap];while(j >= 0 && arr[j] > tmp){arr[j + gap] = arr[j];j -= gap;}arr[j + gap] = tmp;}}}void test(){int arr[] = {3,4,1,2,8,9,5,6,0,7};size_t size = sizeof(arr)/sizeof(arr[0]);ShellSort(arr,size);for(size_t i = 0;i < size;i++){cout<<arr[i]<<" ";}cout<<endl;}int main(){test();return 0;}




选择排序

“test.cpp”

#include<iostream>using namespace std;void SelectSort(int* arr,int size){//最小的放在左边,最大的放在右边int left = 0;int right = size - 1;while(left < right){int min = left;int max = left;for(int i = left;i <= right;i++){if(arr[i] < arr[min])min = i;if(arr[i] > arr[max])max = i;}swap(arr[left],arr[min]);//处理最大的数字在最左边,最小的数字在最右边的情况(图解)if(max == left){max = min;}swap(arr[right],arr[max]);left++;right--;}}void test(){//int arr[] = {2,5,4,9,3,6,8,7,1,0};int arr[] = {9,5,4,2,3,6,8,7,1,0};int size = sizeof(arr)/sizeof(arr[0]);SelectSort(arr,size);for(int i = 0;i < size;++i){cout<<arr[i]<<" ";}cout<<endl;}int main(){test();return 0;}


堆排序

“test.cpp”

#include<iostream>using namespace std;//向下调整void AdjustDown(int* arr,size_t size,int parent){int child = 2 * parent + 1;while(child < size){if(child + 1 < size && arr[child + 1] > arr[child])++child;if(arr[child] > arr[parent])swap(arr[child],arr[parent]);elsebreak;parent = child;child = 2 * parent + 1;}}void HeapSort(int* arr,size_t size){//建堆,从第一个非叶子节点开始向下调整for(int i = (size-2) / 2;i >= 0; --i){AdjustDown(arr,size,i);}//升序,每次取堆顶的数据和最后一个数据进行交换//再对堆顶进行向下调整int end = size - 1;while(end > 0){swap(arr[0],arr[end]);//size的范围逐渐缩小,用end来控制size的大小AdjustDown(arr,end,0);--end;}}void test(){int arr[] = {2,5,4,9,3,6,8,7,1,0};int size = sizeof(arr)/sizeof(arr[0]);HeapSort(arr,size);for(int i = 0;i < size;++i){cout<<arr[i]<<" ";}cout<<endl;}int main(){test();return 0;}

冒泡排序

“test.cpp”

#include<iostream>using namespace std;void BubbleSort(int* arr,size_t size){for(int i = 0;i < size - 1;i++)//趟数{bool flag = false;for(int j = 0;j < size - 1 - i;j++)//比较个数{if(arr[j + 1] < arr[j]){swap(arr[j+1],arr[j]);flag = true;}}if(flag == false)break;}}void test(){int arr[] = {2,6,4,9,0,1,7,3,8,5};int size = sizeof(arr)/sizeof(arr[0]);BubbleSort(arr,size);for(int i = 0;i < size;i++){cout<<arr[i]<<" ";}cout<<endl;}int main(){test();return 0;}

快速排序

“test.cpp”

#include<iostream>using namespace std;#include<stack>//前后指针法int ParkSort3(int* arr,int begin,int end){int key = arr[end];int cur = begin;int prev = begin - 1;while(cur < end){if((arr[cur] < key) && (++prev != cur))swap(arr[cur],arr[prev]);++cur;}swap(arr[++prev],arr[end]);//记住每次交换前prev都要++return prev;}//三数取中法——解决时间复杂度最坏的情况(O(N^2))int GetMidNum(int* arr,int begin,int end){int mid = begin + (end - begin)/2;if(arr[begin] > arr[mid]){if(arr[end] < arr[mid])//arr[mid]是中间值return mid;else//arr[end] > arr[mid]{//此时,arr[mid]是最小的值,中间值在arr[begin],arr[end]中选择if(arr[end] > arr[begin])return begin;else//arr[end] < arr[begin]return end;}}else//arr[begin] < arr[mid]{if(arr[end] > arr[mid])return mid;else//arr[end] < arr[mid]{if(arr[end] > arr[begin])return end;else //arr[end] < arr[begin]return begin;}}}//挖坑法int ParkSort2(int* arr,int begin,int end){int tmp = GetMidNum(arr,begin,end);swap(arr[end],arr[tmp]);int key = arr[end];int left = begin;int right = end;while(left < right){while(left < right && arr[left] <= key)++left;arr[right] = arr[left];while(left < right && arr[right] >= key)--right;arr[left] = arr[right];}arr[left] = key;return left;}//单趟排序int ParkSort1(int* arr,int begin,int end){int left = begin;int right = end - 1;int tmp = GetMidNum(arr,begin,end);swap(arr[end],arr[tmp]);int key = arr[end];while(left < right){//left所指的值要比arr[end](key值)大while(left < right && arr[left] <= key)++left;//right所指的值要比arr[end](key值)小while(left < right && arr[right] >= key)--right;if(left < right)swap(arr[left],arr[right]);}//出了循环以后,此时left和right指向同一个位置,此时//将arr[left](arr[right])的值和arr[end](key值)交换if(arr[left] > key){swap(arr[left],arr[end]);return left;}else return end;}void QuickSort(int* arr,int begin,int end){if(begin >= end)return;//int div = ParkSort1(arr,begin,end);//int div = ParkSort2(arr,begin,end);int div = ParkSort3(arr,begin,end);QuickSort(arr,begin,div-1);QuickSort(arr,div+1,end);}//非递归实现快速排序void QuickSortNonR(int* arr,int begin,int end){stack<int> s;s.push(end);s.push(begin);while(!s.empty()){int left = s.top();s.pop();int right = s.top();s.pop();int div = ParkSort1(arr,left,right);if(left < div - 1){s.push(div-1);s.push(left);}if(div + 1 < right){s.push(right);s.push(div+1);}}}void test(){int arr[] = {5,2,9,0,1,8,3,6,4,7};//int arr[] = {5,2,9};int size = sizeof(arr)/sizeof(arr[0]);//QuickSort(arr,0,size-1);QuickSortNonR(arr,0,size-1);for(int i = 0;i < size;i++){cout<<arr[i]<<" ";}cout<<endl;}int main(){test();return 0;}



归并排序

“test.cpp”

#include<iostream>using namespace std;void Sort(int* arr,int* tmp,int begin,int mid,int end){int index = 0;int left = begin;int right = mid + 1;while(left <= mid && right <= end){if(arr[left] < arr[right])tmp[index++] = arr[left++];elsetmp[index++] = arr[right++];}while(left <= mid)tmp[index++] = arr[left++];while(right <= end)tmp[index++] = arr[right++];index = 0;for(int i = begin;i <= end;++i){arr[i] = tmp[index++];}}void _MergeSort(int* arr,int* tmp,int begin,int end){if(begin >= end)return;int mid = begin + (end - begin)/2;_MergeSort(arr,tmp,begin,mid);_MergeSort(arr,tmp,mid+1,end);Sort(arr,tmp,begin,mid,end);}void MergeSort(int* arr,size_t size){int* tmp = new int[size];_MergeSort(arr,tmp,0,size-1);delete[] tmp;}void test(){int arr[] = {3,8,2,0,7,6,1,5,9,4};//int arr[] = {3,8,2};int size = sizeof(arr)/sizeof(arr[0]);MergeSort(arr,size);for(size_t i = 0;i < size;i++){cout<<arr[i]<<" ";}cout<<endl;}int main(){test();return 0;}

非比较排序

计数排序

“test.cpp”

#include<iostream>using namespace std;void CountSort(int* arr,int size){int min = arr[0];int max = arr[0];for(int i = 1;i < size;++i){if(arr[i] < min)min = arr[i];if(arr[i] > max)max = arr[i];}int range = max - min + 1;int* count = new int[range];for(int i = 0;i < size;++i){count[arr[i] - min]++;}int index = 0;for(int i = 0;i < range;i++){while(count[i] != 0){arr[index++] = i + min;count[i]--;}}}void test(){int arr[] = {5,2,9,6,1,8,7,0,4,3};//int arr[] = {5,2,9};int size = sizeof(arr)/sizeof(arr[0]);CountSort(arr,size);for(int i = 0;i < size;++i){cout<<arr[i]<<" ";}cout<<endl;}int main(){test();return 0;}

基数排序

“test.cpp”

#include<iostream>using namespace std;#include<vector>#include<algorithm>//求数中最大数的位数int GetMaxDigit(int* arr,int size){int base = 10;int digit = 1;for(int i = 0;i < size;++i){while(arr[i] >= base){base *= 10;++digit;}}return digit;}void NewCountSort(int* arr,int size){int digit = GetMaxDigit(arr,size);int base = 1;int* tmp = new int[size];while(digit--){vector<int> count(10);//0-9for(int i = 0;i < size;++i){int num = (arr[i] / base) % 10;count[num]++;}vector<int> start(10);for(int i = 1;i < 10;++i)start[i] = start[i-1] + count[i-1];for(int i = 0;i < size;++i){int num = (arr[i] / base) % 10;//对各个数字进行排序(快速转置的方法)tmp[start[num]++] = arr[i];}//拷贝数值回数组里for(int i = 0;i < size;++i){arr[i] = tmp[i];}//由低位向高位排序base *= 10;}delete[] tmp;}void test(){int arr[] = {4,7,2,0,9,3,6,1,8,5};int size = sizeof(arr)/sizeof(arr[0]);NewCountSort(arr,size);for(int i = 0;i < size;++i){cout<<arr[i]<<" ";}cout<<endl;}int main(){test();return 0;}


0 0
原创粉丝点击