数据结构
插入排序
直接插入排序
前i-1项有序,每次将L(i)插入已有序的子序列
不带哨兵:
void InsertSort(int A[], int n) {
int i, j, temp;
for(i = 1; i < n; i++) {
temp = A[i];
for(j = i - 1; j >= 0 && temp < A[j]; j--) { //找到待插入的位置
A[j + 1] = A[j]; //后移
}
A[j + 1] = temp;
}
}
带哨兵: (用a[0]作为中间变量,减少判断) 数据从a[1]开始存储
void InsertSort2(int A[], int n) {
int i, j;
for(i = 2; i < n; i++) {
A[0] = A[i];
for(j = i - 1; A[0] < A[j]; j--) {
A[j + 1] = A[j];
}
A[j + 1] = A[0];
}
}
折半插入排序
整体思想与直接插入排序类似,在找a[i]要插入的位置时候用折半查找,更快
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 >= high+1; j--) {
A[j + 1] = A[j];
}
A[high + 1] = A[0];
}
}
希尔排序
先把待排序表分成若干的形如L(i,i+d,i+2d,…,i+kd)的子表,对子表进行直接插入排序,然后改变间隔d的大小(变小)再进行直接排序
void ShellSort(int A[], int n) {
int i, j, d;
for (d = n / 2; d > 0; d /= 2){
for (i = d+1; i <= n; ++i) {
if(A[i]<A[i-d]){
A[0] = A[i];
for (j = i - d; j >= 0 && A[0] < A[j]; j -= d) {
A[j + d] = A[j];
}
A[j + d] = A[0];
}
}
}
}
交换排序
冒泡排序
两两比较将,每次将第i大(小)的元素放到正确的位置
每一趟都有一个元素在正确位置上
void BubbleSort(int A[], int n) {
for (int i = 0; i < n - 1; ++i) {
bool flag = false;
for (int j = 0; j < n - i - 1; ++j) {
if (A[j] > A[j + 1]) {
swap(A[j], A[j + 1]);
flag = true;
}
}
if (flag == false){
return;
}
}
}
快速排序
选取一个元素pivot作为枢轴(基准),使得L(1…k-1)中的所有元素都小于pivot,L(k+1…n)中所有元素都大于pivot,然后递归两个子表
int Partition(int A[], 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[low] = pivot;
return low;
}
void QuickSort(int A[], int low, int high) {
if (low < high) {
int pivopos = Partition(A, low, high);
QuickSort(A, low, pivopos - 1);
QuickSort(A, pivopos + 1, high);
}
}
选择排序
简单选择排序
每次选择最小(大)元素,加入有序表。
第i趟,关键字最小的元素与L(i)交换
void SelectSort(int A[], int n) {
for (int i = 0; i < n - 1; ++i) {
int min = i;
for (int j = i + 1; j < n; ++j)
if (A[min] > A[j]) min = j;
if(min != i) swap(A[i], A[min]);
}
}
堆排序
大根堆:根≥左、右(小根堆≤左、右)
每次选取堆顶加入有序表,将堆最底元素放让堆顶,然后调整堆,循环。
//将以k为根的子树调整为大根堆
void HeadAdjust(int A[], int k, int len) {
A[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;
else {
A[k] = A[i];
k = i;
}
}
A[k] = A[0];
}
//建立大根堆
void BuildMaxHeap(int A[], int len) {
for (int i = len / 2; i >= 0; i--) {
HeadAdjust(A, i, len);
}
}
//堆排序
void HeapSort(int A[], int len) {
BuildMaxHeap(A, len);
for (int i = len ; i > 1; i--) {
swap(A[i], A[i]);
HeadAdjust(A, 1, i - 1);
}
}
归并排序
每次将两个或两个以上的有序表合成一个新的有序表
int *B=(int *)malloc(n*sizeof(int)); //辅助数组B
void Merge(int A[], int low, int mid, int high){
int i, j, k;
for (k= low; k <= high; k++){
B[k] = A[k];
}
for(i=low, j=mid+1, k=i; i<=mid && j<=high;k++){
if(B[i] <= B[j]){
A[k] = B[i++];
}else{
A[k] = B[j++];
}
}
while (i<=mid) A[k++] = B[i++];
while (j<=high) A[k++] = B[j++];
}
void MergeSort(int A[], int low, int high){
if(low < high){
int mid = (low + high) / 2;
MergeSort(A, low, mid);
MergeSort(A, mid+1, high);
Merge(A, low, mid, high);
}
}
基数排序
低位优先基数排序:
分配:先考察元素的最低位(个位),一次加入队列中
收集:把队列中的各个结点首位相连
然后考察十位、百位…
测试
int main() {
int n = 10;
// 数组从0开始
int a[10] = { 88, 10, 23, 45, 67, 90, 12, 34, 23, 67};
// 数组从1开始
int b[10] = { 0, 88, 10, 23, 45, 67, 90, 12, 34, 23};
//InsertSort(a, n);
//InsertSort2(b, n);
//InsertSort3(b, n);
//ShellSort(b, n);
//BubbleSort(b, n);
//BubbleSort2(a, n);
//QuickSort(a, 0, n-1);
//SelectSort(a, n);
//HeapSort(a, n);
MergeSort(a, 0, n-1);
cout << "a[]排序后的数组:" << endl;
for(int i = 0; i < n; i++) {
cout << a[i] << " " ;
}
cout << endl;
cout << "b[]排序后的数组:" << endl;
for(int i = 1; i < n; i++) {
cout << b[i] << " ";
}
return 0;
}