首先介绍链式和顺序存储的区别,经常搞混
线性表的顺序存储
又称顺序表,是用一组地址连续的存储单元依次存储线性表中的数据元素,从而使逻辑上相邻的元素在物理地址上也相邻,重点就是逻辑顺序与物理顺序相同.特点 为随机访问 , ,即可以通过首地址和元素序号找到该元素.数组就属于该类型.
链表
通过一组任意的存储单元来存储线性表中的数据元素,一个很大的不同就是,失去了随机访问的特性
插入排序
直接排序插入
前面的为有序序列,每次将元素插入有序序列之中,特点就是每次插完之后,前面插过的元素是有序的,但是不能保证最终顺序是否改变.
相同元素位置不会改变,因此是稳定的,同时适用顺序存储和链式存储
折半插入排序
和直接的区别在于,先折半查找到元素待插位置,减少了比较次数,但是和上面相比,移动次数仍未改变
同时也是稳定的,但是只适用于顺序存储
希尔排序
将原序列分为若干子表,每个子表的间隔为d个元素,然后对于这里面的子表进行直接插入排序,直到增量为1
因为有可能相同的关键词被划分成不同的子表范围,因此是不稳定的,同时需要随机取到相隔为d的元素,因此,也只适用于顺序存储
交换排序
冒泡排序
从后向前,两两比较相邻的元素,若为逆序则交换他们.序列的变化为每次将待排的元素最小的前移到最前面位置,其余元素相对顺序不变.
如果相等就不会发生交换,因此是稳定的排序,同时适用与链式与顺序存储的线性表
快速排序
基本思想来自分治法,在待排序中选择一个枢轴,然后检索剩余元素,将所有小于该枢轴的放到前部分,大于等于的放到后部分,需要注意的是每次枢轴将序列分成两部分,因此在递归操作时,需要将这两部分在进行一次选择枢轴和划分,这称之为一趟.目前是所有排序算法当中平均性能最优的.
在划分时,如果右端存在两个关键字相同,而且小于基准值,则在交换完后相对位置会改变,因此不是稳定排序,同时需要从前向后,和从后向前进行遍历,因此不适合链式(那双向链表应该可以吧)
选择排序
简单选择排序
每一趟选择一个待排序列中的最小值,跑n-1趟自然就排好了
由于代码中写的是寻找 这种挑选是不能保证稳定的,假如加上等于号,每次挑选最小且最靠前的元素即可保证稳定性,因代码而异(稳定与否是可以自己控制的).因为没有涉及随机访问,因此适用与顺序和链式存储
堆排序
将所有元素构建成一棵完全二叉树,大顶堆或者小顶堆,(类似优先队列的实现),需要关注的有两点,一是如何建立初始堆,二是每次输出一个值后,该如何维护该堆的性质不发生变化.
筛选时,有可能把相同关键字的元素调整到前面,因此是不稳定的.需要 只适合顺序存储的
归并排序
将两个有序表合并成一个新的有序表,初始可认为有n个有序的子表,长度为1,每次都两两归并,直至最后合并完成.
不会改变相同关键字的相对次序,是稳定的,适用与顺序和链式存储
基数排序
借助多关键字排序的思想对单逻辑关键字进行的排序,说人话就是,对于每个关键词的各个位置进行分趟排序,例如一个三位数,就是先对个位数,然后十位,百位进行排序,最后获得的序列就是最终序列.
每一趟的分配和收集都是从前向后的,因此不会交换相对位置,是稳定的,同时适用与顺序和链式存储
计数排序
统计出每个待排序的元素,所处于最终结果的位次信息,也就是有多少个元素比他小,然后放到最终数组里面
相同元素相对位置不改变,因此是稳定的,同时更适用于链式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
| #include <bits/stdc++.h> using namespace std;
vector<int> vi; int n = 10; int A[10] = {1,2,8,9,3,4,5,6,7,10}; void print(){ for(int i = 0;i<10;i++) { cout << A[i] <<" "; } cout << "\n"; }
void insertSort(){ for(int i = 2; i< n;i++){ int temp = A[i]; int j = i; while(j > 1 && temp < A[j-1]){ A[j] = A[j-1]; j--; } A[j] = temp; } }
void bubbleSort(){ for(int i = 0;i<n;i++){ int k = i; for(int j = i;j<n;j++){ if(A[j]<A[k]){ k = j; } } swap(A[k],A[i]); } }
int part(int low, int high){ int pivot = A[low]; while (low < high){ while(low < high && A[high] >= pivot) --high; A[low] = A[high]; while(low < high && A[low] <= pivot) ++low; A[high] = A[low]; } A[high] = pivot; return high; }
void quickSort(int low, int high){ if(low >= high) return; int pivotPos = part(low,high); quickSort(low, pivotPos-1); quickSort(pivotPos+1, high); }
void selectSort(){ for(int i = 0;i<n;i++){ int min = i; for (int j = i;j<n;j++){ if(A[j]<A[min]) min = j; } swap(A[i],A[min]); } }
void downAdjust(int low, int high){ int i = low, j = 2*i + 1 ; while(j <= high){ if(j+1 <= high && A[j+1] > A[j]){ j++; } if(A[j] > A[i]){ swap(A[i],A[j]); i = j; j = 2*i+1; }else{ break; } } }
void createHeap(){ for(int i = n/2+1;i>=0;i--){ downAdjust(i,n-1); } }
void heapSort(){ createHeap(); for(int i = n-1;i>0;i--){ cout << A[0] <<" "; swap(A[i],A[0]); downAdjust(1,i-1); } }
int main() { heapSort(); return 0; }
|
堆排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
|
void downAdjust(int low, int high){ int i = low, j = 2*i ; while(j <= high){ if(j+1 <= high && A[j+1] > A[j]){ j++; } if(A[j] > A[i]){ swap(A[i],A[j]); i = j; j = 2*i; }else{ break; } } }
void createHeap(){ for(int i = n/2;i>=1;i--){ downAdjust(i,n); } }
void heapSort(){ createHeap(); for(int i = n;i>0;i--){ cout << A[1] <<" "; swap(A[i],A[1]); downAdjust(1,i-1); } }
void deleteTop(){ A[1] = A[n--]; downAdjust(1,n); }
void upAdjust(int low,int high){ int i = high,j = i / 2; while(j >= low){ if(A[j] < A[i]){ swap(A[j],A[i]); i = j; j /= 2; }else{ break; } } }
void insertHeap(int x){ A[++n] = x; upAdjust(1,n); }
|
递归调整堆排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
void downDie(int u){ int zi = u * 2; if(u*2>n) return; if(zi + 1 <=n && A[zi] < A[zi+1]){ zi++; } if(A[zi] > A[u]){ swap(A[zi],A[u]); downDie(zi); } }
void upDie(int u){ if(u<1) return; int fa = u/2;
if(A[fa] < A[u]){ swap(A[fa],A[u]); upDie(fa); } }
|