数据结构——排序算法
数据结构算法
排序序列默认递增
插入排序
直接插入排序代码
//直接插入排序
void InsertSort(int A[], int n){
int i, j;
for(i = 2; i < n; i++){ //将A[2]-A[n]插入到前面已排序序列
if(A[i] < A[i-1]){ //若A[i]小于前驱,需将A[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 InsertSort(int A[], int n){
int i,j,low,high,mid;
for(i = 2;i <= n; i++){ //将A[2]-A[n]插入到前面已排序序列
A[0] = A[i]; //将A[i]暂存到A[0]
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]; //插入操作
}
}
交换排序
冒泡排序
//冒泡排序
void BubbleSort(int A[], int n){
int i,j;
bool flag;
for(i = 0; i < n-1; i++){
flag = false;
for(j = n-1; j > i; j--){
if(A[j-1] > A[j]){ //若为逆序
swap(A[j-1], A[j]); //交换
flag = true;
}
}
if(flag == false)
{
return ; //本趟遍历后没有发生交换,说明表已经有序
}
}
}
快速排序
//快速排序
//Partition()就是划分操作,将表A[low,...,high]划分为满足条件的两个子表
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 pivotpos = Partition(A, low, high); //划分
QuickSort(A, low, pivotpos-1); //依次对两个子表进行递归排序
QuickSort(A, pivotpos+1, high);
}
}
选择排序
简单选择排序
//简单选择排序
void SelectSort(int A[], int n){
//从A[0]开始存放元素
int i,min;
for(i = 0; i < n-1; i++){
min = i;
for(j = i+1; j < n; j++){
if(A[j] < A[min]){
min = j; //更新最小元素位置
}
}
if(min != i){
swap(A[i], A[min]); //与第i个位置交换
}
}
}
堆排序
堆排序,最大堆用于递增排序,最小堆用于递减排序
//将元素k向下调整
void AdjustDown(int A[], int k, int len){
int i;
A[0] = A[k]; //A[0]暂存元素k
for(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]; //将A[i]调整到父节点处,不用管父节点原来的值,因为在A[0]暂存
k = i; //修改k的值,继续向下筛选
}
}
A[k] = A[0]; //被筛选的节点放入最终位置
}
//建立大根堆
void BuildMaxHeap(int A[], int len){
for(int i = len/2; i > 0; i--){ //从i = [n/2]~1,反复调整堆
AdjustDown(A,i,len);
}
}
//堆排序
void HeapSort(int A[], int len){
BuildMaxHeap(A,len);
int i;
for(i = len; i > 1; i--){
swap(A[i],A[1]); //将堆顶元素和堆底元素交换
AdjustDown(A,1,i-1);
}
}
int main(){
int a[8] = {0,7,9,2,4,6,8,10};
HeapSort(a, 7);
for(int i =1;i<8;i++){
cout<<a[i]<<" ";
}
return 0;
}
归并排序
//归并排序
int *B=(int *)malloc((n+1)*sizeof(int)); //辅助数组B
void Merge(int A[], int low, int mid, int high){
//表A的两段A[low,...,mid]和A[mid+1,...,high]各自有序,将它们合并成一个有序表
for(int k=low; k<=high; k++){
B[k] = A[k]; //将A中所有元素复制到B中
}
for(int i= low,int j =mid+1, int k=i; i<=mid&&j<=high;k++){
if(B[i] <= B[j]){ //比较B的左右两段中的元素,将较小值复制到A中
A[k] = B[i];
i++;
}else{
A[k] = B[j];
j++;
}
}//for
//以下两个while()循环只有一个会执行
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);
}
}