日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

王道八大排序:直接插入排序 折半插入排序 希尔排序 冒泡排序 快速排序 归并排序 基数排序

發布時間:2024/3/13 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 王道八大排序:直接插入排序 折半插入排序 希尔排序 冒泡排序 快速排序 归并排序 基数排序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 1、插入排序
    • 1.1直接插入排序
    • 1.2折半插入排序
    • 1.3希爾排序
  • 2、交換排序
    • 2.1冒泡排序
    • 2.2快速排序
  • 3、選擇排序
    • 3.1簡單選擇排序
    • 3.2堆排序
  • 4、歸并排序
  • 5、基數排序

1、插入排序

1.1直接插入排序

直接插入排序:每次將當前元素按照其大小插入到前面已有序的子序列中。

//arr[0~n-1]存數據; void InsertSort(int arr[], int n){int i, j, temp;//遍歷數組for (i = 1; i < n; i++){//當前元素的前驅大于當前元素if (arr[i - 1] > arr[i]) {temp = arr[i]; //保存arr[i]//將前面有序序列中的所有大于arr[i]的值全部后移一位for (j = i - 1; j >= 0 && arr[j] > temp; j--){arr[j + 1] = arr[j];}arr[j + 1] = temp; //將原arr[i]賦值給arr[j + 1]}//if}//for }

1.2折半插入排序

折半插入排序:與折半查找類似,逐一遍歷數組元素,在數組前面有序的序列中找到該元素的位置

void InsertSort(int arr[], int n) {int i, low, high, mid;//用arr[1~n]存數,arr[0]保存當前元素,將arr[1]視為有序;for (i = 2; i<=n; i++) { arr[0] = arr[i]; //初始化low和high指針分別為第一個元素和第i - 1個元素low = 1;high = i - 1;//循環直到low > high,查找當前元素在當前序列中的位置while (low <= high) {mid = (high + low) / 2; //更新mid//mid指向的元素小于arr[0],去左半邊繼續排序if (arr[0] < arr[mid]) high = mid - 1;//mid指向的元素大于等于arr[0],去右半邊,這是該算法穩定的原因else low = mid + 1;}//從arr[high+1]或arr[low]元素統一后移for (int j = i - 1; j >= high+1; j--) {arr[j+1] = arr[j ];}//在arr[high+1]或arr[low]處插入元素arr[high+1] = arr[0];}//for }

1.3希爾排序

希爾排序:把相隔某個增量的元素組成一個子表,對各個子表進行直接插入排序,當整個表中基本有序的時候,再對整個表進行一次直接插入排序。

void ShellSort(int arr[], int n) {int d;//初始化d為n/2,每一輪d為上一輪的1/2for (d = n / 2; d >= 1; d /= 2) {//從每個分組的第二個元素開始,遍歷剩余元素,進行直接插入排序for (int i = d+1; i <= n; i++) {if (arr[i] < arr[i - d]) { //將arr[i]直接插入有序增量子表(組間元素對比)arr[0] = arr[i]; //暫存arr[0]int j;for (j = i - d; j > 0 && arr[j] > arr[0]; j -= d) {arr[j + d] = arr[j]; //記錄后移}arr[j + d] = arr[0]; //插入}//if}//for}//for }

2、交換排序

2.1冒泡排序

冒泡排序:從后往前兩兩比較相鄰元素的值,若為逆序,則交換。

//交換 void swap(int& a, int& b) {int temp = a;a = b;b = temp; } //冒泡排序 void BubbleSort(int arr[], int n) {for (int i = 0; i < n - 1; i++) {bool flag = false;//標記此輪循環中是否發生交換//每次從數組中最后1個元素向前遍歷,直到第i個元素for (int j = n - 1; j > i; j--) {//將相鄰兩個元素為逆序,則交換,并更改flag。if (arr[j - 1] > arr[j]) {swap(arr[j - 1], arr[j]);flag = true;}}//for//此次循環元素都是正序,則結束函數if (flag==false) return;}//for }

2.2快速排序

快速排序
1、取當前表中的第1個元素為基準元素,找到它在表中的位置,即左邊元素都小于它,右邊元素都大于等于它,這樣就確定了基準元素的最終位置。
2、以它為分割,遞歸的對兩個子表進行上述操作,直到每個表都只有1個或0個元素為止。

void swap(int& a, int& b) {int temp = a;a = b;b = temp; } void quicksort(int arr[], int L, int R) {if (L >= R) return; //當前區間中元素為1或0,則退出int pivot, i = L, j = R; //i,j是兩個數組下標移動//此處可做優化,將任意一個元素與arr[L]交換pivot = arr[L];while (i < j) {while (i<j && arr[j]>pivot) j--;while (i < j && arr[i] <= pivot)i++;if (i < j) //避免++--之后不滿足i<j;swap(arr[i], arr[j]);}swap(arr[L], arr[i]);//此時A[L~i-1] <= A[i]<=A[i+1~R];quicksort(arr, L, i - 1); //遞歸左區間quicksort(arr, i + 1, R);//遞歸右區間 }

3、選擇排序

3.1簡單選擇排序

簡單選擇排序:遍歷數組,每次找到一個最小的元素插入到待排序表的表頭位置。

//交換元素 void swap(int& a, int& b) {int temp = a;a = b;b = temp; } //簡單選擇排序 void SelectSort(int arr[], int n) {//遍歷數組 arr[0~n-2] 最后一個元素arr[n-1]不用遍歷;for (int i = 0; i < n-1; i++) {int min = i; //標記未排序數列中最小值元素的下標,初始為第 i 個元素;for (int j = i + 1; j< n; j++) { //從i + 1開始遍歷數組if (arr[j] < arr[min]) min = j;}//for完之后min指向未排序數列中最小值元素的下標if(min!=i) swap(arr[i], arr[min]); //交換第 i 個元素和最小值元素} }

3.2堆排序

堆排序
1、首先建成大根堆,即堆頂元素大于左右子樹的值,左右子樹也滿足該特性。
2、輸出堆頂元素,將堆底元素送入堆頂,此時堆特性被破壞,將堆頂元素向下調整直到滿足堆特性,再輸出堆頂元素。
3、如此重復,直到堆中只剩一個元素為止。

//調整以k為子樹的大根堆 (arr[0]中自始至終只存過arr[k]) void HeadAdjust(int arr[],int k,int len) {arr[0] = arr[k]; //arr[0]保存第k個元素for (int i = 2 * k; i <= len; i *= 2) {if (i < len&& arr[i] < arr[i + 1]) i++; //判斷左右孩子誰更大,i指向更大的孩子;if(arr[0]>=arr[i]) break; //根節點arr[0]與大孩子的值比較,大于,則篩選結束。else { arr[k] = arr[i]; //小于,則將大孩子arr[i]調整到雙親節點上。k = i; //調整k值,以便繼續向下篩選。}}//forarr[k] = arr[0]; //被篩選節點的值放入最終位置 }void BuildMaxHeap(int arr[], int len) {//從分支節點開始從后往前,向上遍歷調整;for (int i = len / 2; i > 0; i--) {HeadAdjust(arr,i,len); //調整以i為子樹的大根堆} }//大根堆排序 void HeapSort(int arr[], int len) {BuildMaxHeap(arr, len);//從后往前遍歷數組for (int i = len; i > 1; i--) {swap(arr[i], arr[1]); //交換堆頂元素和堆底元素HeadAdjust(arr,1, i-1);//調整大根堆} }

4、歸并排序

歸并排序:將兩個或多個有序表合并成一個有序表。

//Merge()函數:將前后兩個有序表歸并成一個有序表 int *B= (int*)malloc(sizeof(int) * (maxsize+1)); //輔助數組B[] void Merge(int A[], int L, int mid, int R) {for (int k = L; k <= R; k++)B[k] = A[k]; //將A數組元素復制到B中int i, j, k;//遍歷數組for (i = L, j =mid+1, k = i; i<= mid && j<= R; k++) {if (B[i] <= B[j]) A[k] = B[i++]; //比較B中的左右子表中的元素大小,兩個子表若元素相同,則優先選擇左子表else A[k] =B[j++]; //將較小值復制到A中}//將剩余元素插入到表中while (i <= mid) A[k++] = B[i++];//若一個表未檢測完,復制while (j <= R) A[k++] = B[j++]; //若二個表未檢測完,復制 }void MergeSort(int A[], int L, int R) {if (L < R) {int mid =(L+ R) / 2;//從中間劃分兩個子序列MergeSort(A, L, mid);//對左子表進行遞歸排序MergeSort(A, mid + 1, R); //對右子表進行遞歸排序Merge(A, L,mid, R); //歸并}//if }

5、基數排序

基數排序
不基于比較和移動元素來進行排序,它將一個邏輯關鍵字分為多個關鍵字,基于關鍵字各位的大小進行排序的。

在排序的過程中,需要使用r個隊列。排序過程如下:
分配:開始時,把各個隊列置為空隊列,然后依次考察待排元素的關鍵字大小,把元素放入與關鍵字大小對應的隊列中。
收集:把各個隊列中的結點首尾相接,得到新的元素序列,從而組成新的線性表。
重復分配-收集的過程,直到有序。

總結

以上是生活随笔為你收集整理的王道八大排序:直接插入排序 折半插入排序 希尔排序 冒泡排序 快速排序 归并排序 基数排序的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。