直冒简希 快堆二基
1. 直接插入排序
思路(先找位置后填充)
- 将n个元素序列分为无序序列和有序列
- 每次从后部的无序序列中选择第一个元素,从后向前和有序序列的元素进行比较并挪移
- 找到插入的位置后填充
哨兵:在进行大量数据比较时,在数据边界放置特别的元素进行标注,避免每次比较是否越界而浪费时间
void InsertSort(ElemType A[], int n){
int i, j;
for(i = 2; i <= n; i++) //第一个元素默认有序,每次从无序序列中挑选第一个进行排序
if(A[i] < A[i-1]){ //无序序列的第一个元素比有序序列的最后一个元素小才需要排序
A[0] = A[i]; //将A[0]作为哨兵元素
for(j = i-1; A[j] > A[0]; --j) //找位置
A[j+1] = A[j]; //向后挪位
A[j+1] = A[0]; //将元素填充到目标位置
}
}
2. 冒泡排序
思想
- 每一次排序都会将无序区的最小元素放到有序区的目标位置
void bubbleSort(int R[], int n){
int i, j, temp, exchange;
for(i = 0; i < n-1; i++){//进行n-1次排序,最后一个自动有序
exchange = 0; //没有发生交换则只排序一次
for(j = n-2; j >= i; j--)
if(R[j+1] < R[j]){//小的下沉
temp = R[j+1];
R[j+1] = R[j];
R[j] = temp;
exchange = 1;
}
if(!exchange) //没有发生交换则是完全有序
break;
}
}
3. 简单选择排序
思路
- 从无序区中找最小的与有序区的相应位置元素进行交换
int main(){
int A[10];
selectSort(A, 10);
}
//数组指针进行传址交换,传值交换无法成功
void selectSort(int *p, int n){
int i, j, min;
for(i = 0; i < n-1; i++){
min = i;
for(j = i+1; j < n; i++;){
if(p[i] < p[j])
min = j;
if(min != i)
swap(p[i], p[min]);
}
}
}
希尔排序(缩小增量排序)
void shellSort(ElemType A[], int n){
for(dk = n / 2; dk >= 1; dk = dk / 2)
for(i = dk+1; i < n; ++i)
if(A[i] < A[i-dk]){
A[0] = A[i];
for(j = i-dk; j > 0&&A[0]<A[j]; j-=dk)
A[j+dk] = A[j];
A[j+dk] = A[0];
}
}
快速排序
思想:
- 每次快排让枢纽元素处在最终位置,该元素之前的均小,该元素之后的均大
- 表本身有序或逆序最慢,每次枢纽能将表等分为长度相近的两个子表时最快
int Partition(ElemType A[], int low, int high){
ElemType pivot = A[low];
while(low < high){
while(low < high && A[high] >= pivot) //确定位置
--high; //从后向前找比枢纽小的元素
A[low] = A[high]; //将比枢纽小的元素向前填充
while(low < high && A[low] <= piovt) //确定位置
++low; //从前向后找比枢纽大的元素
A[high] = A[low]; //将比枢纽大的元素向后填充
}
A[low] = pivot; //将枢纽元素存储到最终的划分位置
return low; //返回枢纽元素最终位置
}
void QuickSort(ElemType A[], int low, int high){
if(low < high){
int pivotpos = partition(A, low, high); //确定划分的位置
QuickSort(A, low, pivotpos-1); //递归进行左划分
QuickSort(A, pivotpos+1, high); //递归进行右划分
}
}