1、插入排序:

1)直接插入排序:

哨兵版:
void insertSort(int A[], int n)
{int i, j;for(i = 2; i <= n; i++){A[0] = A[i];         //负责为哨兵,A[0]不存放元素 for(j = i - 1; A[0] < A[j]; j--)A[j+1] = A[j];A[j+1] = A[0];}
}
普通版:
void insertSort2(int A[], int n)
{int i, j;int temp; for(i = 1; i < n; i++){//A[0]放元素if(A[i] < A[i-1]) {temp = A[i];   //暂存A[i];for(j = i-1; j >= 0 &&A[j] > temp; --j)A[j+1] = A[j];A[j+1] = temp;} }
}

2)折半插入排序:在排好的序的部分折半查找插入位置

void insertSort3(int A[], int n)
{int i,j,low,high,mid;for(i = 2; i <= n; i++){A[0] = A[i];low = 1; high = i - 1;while(low <= high){mid = (low + high)/2;if(A[mid] > A[0]) high = mid - 1;else low = mid+1;}for(j = i-1; j >= low; --j){//low指向要插入的位置low==high+1 A[j+1] = A[j];} A[low] = A[0];}
}


2、希尔排序:

严版:


void shellInsert(int A[],int n,int dk)
{int i, j;for(i = 1+dk; i <= n; i++){//对增量为dk的序列进行直接插入排序 if(A[i] < A[i-dk]){A[0] = A[i];     //暂存A[i]非哨兵,A[0]不存放元素;也可用temp代替 for(j = i-dk; j > 0 && A[0] > A[j]; j -= dk)A[j+dk] = A[j];A[j+dk] = A[0]; }}
}void shellSort(int A[], int n, int delta[], int t)
{//A为待排序列,n为其长度,delta为增量序列,t为其长度 for(int k = 0; k < t; k++){//一个增量一趟 shellInsert(A, n, delta[k]);}
}

3、冒泡排序:

void swap(int &a,int &b)
{int temp = a;a = b;b = temp;
}void bubbleSort(int A[], int n)
{//升序,从后往前冒 for(int i = 0; i < n-1; i++){bool flag = false;   //本趟是否发生过交换 for(int j=n-1; j > i; j--){if(A[j] < A[j-1]){swap(A[j], A[j-1]);flag = true; }}if(flag == false) //没有交换过,则已是升序 return ;}
}

4、快速排序:找到的所有版本,区别就是partition

1)初始版本:

#include<iostream>using namespace std;
int partition(int A[],int low,int high)
{int pivotkey = A[low]; //选左边第一个pivotkey int start = low; //暂存pivotkey的下标 while(low < high){while(low < high && A[high] >= pivotkey) high--;while(low < high && A[low] <= pivotkey) low++;if(low < high){swap(A[low],A[high]);} }swap(A[low],A[start]);  //此时low == high,且A[low]必然是小于等于pivotkey的 return low;
}
void QSort(int A[], int low, int high)
{if(low < high){int pivotloc = partition(A, low, high);QSort(A, low, pivotloc-1);QSort(A, pivotloc+1, high);}
}
void QuickSort(int A[], int n)
{QSort(A,0,n-1);
}
int main()
{int A[10] = {4,2,1,4,5,6,7,8,9,3}; QuickSort(A,10);for(int i = 0; i < 10; i++){cout<<A[i]<<endl;}return 0;
}

2)挖坑法:对上面的改进,严书上只有这个(但是暨大考过其他版本的,所以汇总下)

#include<iostream>
using namespace std;
int partition(int A[],int low,int high)
{int pivotkey = A[low];while(low < high){while(low < high && A[high] >= pivotkey) high--;A[low] = A[high];while(low < high && A[low] <= pivotkey) low++;A[high] = A[low];}A[low] = pivotkey;return low;
} 

3)前后指针法:

最右边的枢纽:
int partition(int A[],int low,int high)
{int pivotkey = A[high]; //最右边为枢纽int i = low - 1;for(int j = low; j <= high-1; j++){if(A[j] < pivotkey){i++;swap(A[i], A[j]); }} swap(A[i+1],A[high]);   //[low,i]、i+1、[i+2,high] return i+1;
}
最左边的为枢纽:
int partition(int A[],int low,int high)
{int pivotkey = A[low]; //最左边为枢纽int i = high+1;for(int j = high; j > 0; j--){if(A[j] > pivotkey){i--;swap(A[i], A[j]); }} swap(A[i-1],A[low]);   //[low,i]、i+1、[i+2,high] return i-1;
}
王道这样写的,感觉好点
int partition(int A[],int low,int high)
{int pivotkey = A[low]; //最左边为枢纽int i = low;for(int j = low+1; j <= high; j++){if(A[j] < pivotkey){swap(A[++i], A[j]); }} swap(A[i],A[low]);return i;
}
随机位置:
int partition(int A[], int low,int high)
{int random_index = rand()%(high-low+1);swap(A[low],A[random_index]);int pivotkey = A[low];while(low < high){while(low < high && A[high] >= pivotkey)high--;A[low] = A[high]; while(low < high && A[low] <= pivotkey) low++;A[high] = A[low];} A[low] = pivotkey;return low;
}
int partition(int A[], int low, int high)
{int random_index = rand()%(high-low+1);swap(A[low],A[random_index]);int pivotkey = A[low];int i = low;for(int j = low+1;j <= high; j++){if(A[j] < pivotkey){swap(A[++i],A[j]);}}swap(A[i],A[low]);return i;
}
暨大考题2020:填空
int partition(int* A, int N, int p, int r)
{     int x = A[r];int i =   //(5)   ;for (int j = p; j<=r-1; j++){if (   //(6)   ){i = i + 1;int temp = A[i];A[i] = A[j];A[j] = temp;}}int temp = A[i+1];A[i+1] = A[r];A[r] = temp;return   //(7)  ;
}
void QuickSort(int* A, int N, int p, int r)
{int q;if (   //(8)  ){q = partition(A, N, p, r);QuickSort(    //(9)    );QuickSort(    //(10)   );}return;
}
void main()
{     QuickSort(A, N, 0,N-1);return 0;
}

4)Hoare分区方案:第1个版本的另一种写法

int partition(int arr[],int low, int hight)
{int pivot = arr[low]; int i = low - 1;int j = hight + 1; while(true){while(arr[++i] < pivot);     //找 >= pivot的 while(arr[--j] > pivot);       //找 <= piovt的if(i >= j){return j;}  swap(arr[i],arr[j]);}
}

5)非递归版本:分区用哪个版本无所谓

#include<iostream>
#include<stack>using namespace std;int partition(int A[],int low,int high)
{int pivotkey = A[low];while(low < high){while(low < high && A[high] >= pivotkey) high--;A[low] = A[high];while(low < high && A[low] <= pivotkey) low++;A[high] = A[low];}A[low] = pivotkey;return low;
}
void QSort(int A[], int low, int high)
{stack<int>stk;if(low < high){stk.push(low);  //先左后右进栈,先右后左出栈 stk.push(high);while(!stk.empty()){int right = stk.top(); stk.pop();int left = stk.top(); stk.pop();int pivotloc = partition(A,left, right);  //枢纽下标 if(left < pivotloc - 1){//左边还有两个及以上的元素 stk.push(left); stk.push(pivotloc-1);}if(right > pivotloc + 1){//左边还有两个及以上的元素 stk.push(pivotloc+1);stk.push(right);    }}}
}
void QuickSort(int A[], int n)
{QSort(A,0,n-1);
}
int main()
{int A[10] = {4,2,1,4,5,6,7,8,9,3}; QuickSort(A,10);for(int i = 0; i < 10; i++){cout<<A[i]<<endl;}return 0;
}
队列版:
void QSort(int A[], int low, int high)
{queue<int>q;if(low < high){q.push(low);  q.push(high);while(!q.empty()){int left = q.front(); q.pop();int right = q.front(); q.pop();int pivotloc = partition(A,left, right);  //枢纽下标 if(left < pivotloc - 1){//左边还有两个及以上的元素 q.push(left); q.push(pivotloc-1);}if(right > pivotloc + 1){//左边还有两个及以上的元素 q.push(pivotloc+1);q.push(right);   }}}
}

快排扩展:第k小的数

int kth_elem(int A[],int low, int high, int k)
{int pivot = A[low];int left = low;int right = high;while(left < right){while(left < right && A[right] >= pivot) right--;A[left] = A[right];while(left < right && A[left] <= pivot) left++;A[right] = A[left];}A[left] = pivot;  //left == right//上面和快排分区没什么不同if(left == k){return A[left];}else if(left > k){return kth_elem(A, low, left-1, k);} else{return kth_elem(A, left+1, high, k);   }
}

5、堆排序:

顺序存储的完全二叉树下标
  • 0开始时,n个结点,最大分支结点编号是((n-1)-1)/2,双亲编号是(i-1)/2,都是向下取整.
  • 1开始时,n个结点,最大分支结点编号是n/2,双亲编号是i/2,都是向下取整。
基于大根堆:下标从1开始
void HeapAdjust(int A[], int k, int len)
{//自顶向下调整siftDownA[0] = A[k];for(int i = 2*k; i < len; i*=2){if(i < len && A[i] < A[i+1]){i++;  //取较大的子女下标 }if(A[0] >= A[i]) break;A[k] = A[i];k = i;} A[k] = A[0];
}
void BuildMaxHeap(int A[], int len)
{//建堆   for(int i = len/2; i > 0; i--){//len/2是编号最大的分支结点 HeapAdjust(A, i, len);}
}
void HeapSort(int A[], int len)
{BuildMaxHeap(A,len);   //建立初始大根堆for(int i = len; i > 1; i--){swap(A[i], A[1]);   //输出堆顶元素(输出到堆底) HeapAdjust(A, 1, i-1); //调整,把剩下的i-1个元素组成堆 }
}
小根堆:下标从0开始(多写了,加了插入和删除,如果只是用小根堆来排序不用写这么麻烦)
const int heapSize = 50;
typedef int HElemType;
typedef struct {HElemType elem[heapSize]; int curSize;
}minHeap;void siftDown(minHeap &heap, int i, int n)
{HElemType cur = heap.elem[i]; //i是双亲,j是i的值更小的子女 for(int j = 2*i+1; j < n; j = 2*j +1){if(j < n-1 && heap.elem[j] > heap.elem[j+1]) j++;   //有右兄弟,且右兄弟更小if(cur <= heap.elem[j]) break; //双亲比子女更小,停止向下 else{heap.elem[i] = heap.elem[j]; //双亲比子女 i = j;} }  heap[i] = cur;
}
viod siftUp(minHeap &heap, int start)
{//自底向下调整小根堆HElemType cur = heap.elem[start];int j = start; //j是子女int i = (j-1)/2;  //i是j的双亲 while(j > 0){if(heap.elem[i] <= cur) break;     //双亲更小停止向上else{heap.elem[j] = heap.elem[i]; //双亲比子女大,让子女上去(把双亲拉下来) j = i;          //上一层 i = (i-1)/2;   //上一层 } } heap.elem[j] = cur;
}
void insert(minHeap &heap, int x)
{if(heap.curSize == heapSize) return false;heap.elem[heap.curSize] = x;siftUp(heap,heap.curSize);heap.curSize++; return true;
}
void delete(minHeap &heap, int &x)
{//删除堆顶元素,并赋值给xif(heap.curSize == 0) return false;x = heap.elem[0]; heap.elem[0] = heap.elem[--heap.curSize];siftDown(heap, 0, heap.curSize);return true;
}
void creatMinHeap(minHeap &heap, ElemType arr[], int n)
{//创建小根堆 for(int i = 0; i < n; i++) heap.elem[i] = arr[i];heap.curSize = n;for(int i = (n-2)/2; i >= 0; i--){siftDown(heap, i, heap.curSize);}
}
HElemType* heapSort(minHeap heap)
{HElemType *res = new HElemType[heap.curSize];int j = 0;for(int i = heap.curSize-1; i >= 0; i--){res[j++] = heap.elem[0];swap(heap.elem[i],heap.elem[0]);siftDown(heap, 0, i); } //heap不是小根堆了 return res;
}

判断是不是小根堆:

bool isMinHeap(int A[], int len)
{if(len%2 == 0) //len为偶数有一个单分支结点且是编号最大的分支结点 {if(A[(len-2)/2] > A[len-1]){return false; }for(int i = (len-2)/2-1; i >= 0; i--){if(A[i] > A[2*i+1] || A[i] > A[2*i+2]){return false;}}} else{for(int i = (len-2)/2; i >= 0; i--){if(A[i] > A[2*i+1] || A[i] > A[2*i+2]){return false;}}}
}



6、归并排序:

以前写的:归并排序

迭代版本:

void MergeSort(int arr[],int len)
{int *a = arr;int *b = new int[len];   //辅助数组 for(int seg=1; seg < len; seg += seg){for(int start = 0; start < len; start += seg*2){int low = start, mid = min(start+seg, len), high = min(start+seg*2,len);int k = low;int start1 = low, end1 = mid;int start2 = mid, end2 = high;while(start1 < end1 && start2 < end2)b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];while(start1 < end1) b[k++] = a[start1++];while(start2 < end2)b[k++] = a[start2++];}int *temp = a;   //交换a和b的指向,让b下一轮还是指向辅助数组 a = b;           //交换会让arr和辅助数组的地位在下一轮中互换 b = temp;     //而每轮循环结束后,a都指向本轮归并结果数组 }//结束上面语句后a指向的是排序后的数组,但因为arr和一开始的辅助数组角色互换//所以,如果 a != arr就说明最后一轮arr是被当作辅助数组用的//注:arr的指向是不会变的 if(a != arr){for(int i = 0; i < len; i++){b[i] = a[i]; //或者写成arr[i] = a[i];} b = a; } delete [] b;
}

递归版本:


void Merge(int A[], int temp[], int low, int mid, int high)
{for(int k = low; k <= high; k++){temp[k] = A[k];}for(int i = low, j= mid + 1, k = i;i <= mid&&j <=high; k++){if(temp[i] <= temp[j])  A[k] = B[i++];else A[k] = B[j++]; } while(i <= mid) A[k++] = temp[i++];while(j <= high) A[k++] = temp[j++];
}
void MSort(int A[],int temp[],int low,int high)
{if(low < high){int mid = (high - mid)/2;MSort(A, temp, low, mid);MSort(A, temp, mid+1, high);Merge(A, temp, low, mid, high);}
}
void MergeSort(int A[], int low, int high, int n)
{int *temp = new int[n];MSort(A, temp, low, high);
}

7、基数排序:

基数排序分两种:最高位优先MSD(Most Significant Digit first)和最低位优先LSD(Least Significant Digit first),MSD应该不考,以后再看,下面代码基于LSD.
#include<iostream>
#include<queue>using namespace std;int power(int di)
{int res = 1;for(int i = 0; i < di; i++) res *= 10;return res;
}
void print(int A[],int len)
{for(int i = 0; i < len; i++){cout<<A[i]<<"  ";} cout<<endl;
}
void RadixSort(int A[], int len, int d)
{//print(A,len);queue<int>qarr[10];for(int i = 0; i < d; i++){//分配 int pow = power(i);for(int j = 0; j < len; j++){ int index = A[j]/pow% 10;qarr[index].push(A[j]); }//收集,按qarr[0]、qarr[1].....收集结果为升序,反之为降序int k = 0;for(int j = 0; j < 10; j++)  {while(!qarr[j].empty()){int cur = qarr[j].front(); qarr[j].pop();A[k++] = cur;}}} //print(A,len);
}
int main()
{int A[10] = {105,12, 3, 45,47, 31, 5,6,9,567};RadixSort(A,10,3);return 0;
}
注:上面代码不能处理负数情况,负数应该也不考




可以参考

考研数据结构--排序汇总(自用)相关推荐

  1. 考研[*数据结构*]学习笔记汇总(全)

    文章目录: 一:预备阶段 二:基础阶段笔记 三:冲刺阶段笔记 四:各章节思维导图 五:题库 来源:王道计算机考研 数据结构 一:预备阶段 之前的数据结构笔记 数据结构--学习笔记--入门必看[建议收藏 ...

  2. 数据结构 排序【简单排序(冒泡、插入)、希尔排序、堆排序、排序方法的综合比较、2套 排序汇总代码】

    目   录 第9章 排序(上) 9.1 简单排序(冒泡.插入) 1.前提 2.简单排序(冒泡排序) 3.简单排序(插入排序) 4.时间复杂度下界 9.2 希尔排序 9.3 堆排序 排序方法综合比较 排 ...

  3. 北航计算机学院往年夏令营+考研面试题目汇总

    北航计算机学院硕士复试机经+面经: 北航计算机学院往年夏令营+预推免机试题目汇总 北航计算机学院往年夏令营+考研面试题目汇总 北航计算机学院往年夏令营+考研面试数理题目汇总 以下是我在网络上找到的北航 ...

  4. (王道408考研数据结构)第五章树-第四节2:平衡二叉树(AVL)及其旋转

    文章目录 一:AVL树基本概念 二:AVL树实现原理 (1)构建AVL树 (2)构建演示 (3)旋转方法 A:右单旋转调整(插入到较高左子树左侧) B:左单旋转调整(插入到较高右子树右侧) C:先左后 ...

  5. 计算机考研数据结构算法模板

    计算机考研数据结构算法模板 前言 临近考研,想给考研党们分享一些比较通用的算法模板,让复习更高效一点.如果备考时间足够长,备考人应该有大量时间刷大量习题,会有自己总结的算法模板,笔者文章参考了王道考研 ...

  6. 厦门大学计算机科学专业,2018厦门大学计算机科学系考研招生信息汇总

    原标题:2018厦门大学计算机科学系考研招生信息汇总 选择决定命运,成败在于坚持,既然选择了考研,说什么也别放弃,其实成功就是在艰难时刻的最后一次坚持!为了帮助2018年准备考研的备考生们尽快进入复习 ...

  7. 考研数据结构填空题整合_做题版

    考研数据结构填空题整合 目录 考研数据结构填空题整合 一.ZYL组 ZYL组一 ZYL组二 ZYL组三 ZYL组四 ZYL组五 ZYL组六 ZYL组七 ZYL组八 二.TJP组 TJP组一 TJP组二 ...

  8. 二、考研数据结构笔记——绪论(理解数据结构,算法,时间复杂度计算做题技巧)

    一.数据结构基本概念 1.数据:数据是信息的载体.客观事物的一种表现形式.万事万物都能用数据表示出来. 2.数据元素:数据元素是数据的基本单位,一个数据元素有若干个数据项组成 3.数据项:构成数据元素 ...

  9. 考研数据结构判断题整合

    考研数据结构判断题整合 目录 考研数据结构判断题整合 一.ZYL组 ZYL组一 ZYL组二 ZYL组三 ZYL组四 ZYL组五 ZYL组六 ZYL组七 ZYL组八 二.TJP组 TJP组一 TJP组二 ...

最新文章

  1. PostgreSQL 数据库备份
  2. Windows下各个盘中的文件夹属性变为隐藏,怎么取消隐藏属性
  3. 三步在MacOS Anaconda安装ligthGBM
  4. go mysql use 问题,Go语言使用MySql的方法
  5. 比拼 Kafka, 大数据分析新秀Pulsar到底好在哪
  6. matlab 样本均值,Matlab | Matlab从入门到放弃(4)——样本均值
  7. Python 分析在德的中国程序员,告别 996 ?
  8. 信念很简单,把书念下去,然后走出去,不枉活一世 —转自动化所一篇博士论文致谢...
  9. ubuntu上搭建wiki系统
  10. web实现全景图的交互展示
  11. 估计值与平均值的离差平方和_各变量值与其算术平均数的离差平方之和为()
  12. HTTP协议有关知识
  13. 南理工计算机专业好吗,吉大计算机or南理工计算机?(江苏考生)
  14. python基础什么是函数的定义及用法
  15. 微信小程序地图图标controltap
  16. iOS开发中Touch ID的使用
  17. 【国际】塞拉利昂重点发展国家区块链计划
  18. 我要写王者荣耀类游戏的网页代码
  19. 佟丽娅现身活动火力全开 黑色裹身裙时髦大气,未修图也美的惊艳
  20. the unfamiliar words and sentences of《The Great Gatsby》1

热门文章

  1. 自学python考哪些证书-【经验分享】想转行学python,过来人提醒大家几点
  2. python编程教学软件-编程教学平台的python编辑器的开发
  3. python画图代码大全-Python实现画图软件功能方法详解
  4. python3入门代码-Python3 入门教程 简单但比较不错
  5. 一张图学会python应用到excel-Python应用之------Excel操作
  6. python语言的读法-Python语言的特点及自学建议
  7. 什么是车联网?导航?听歌?智能语音识别?事实没这么简单!
  8. QYResearch回顾:2017年中国汽车语音识别系统产量为1413万
  9. 谷歌称语音识别是下一个机会,尤其在发展中国家
  10. heroku创建linux主机,将Yesod部署到Heroku,无法静态构建