6种排序算法合集(C语言)

1 篇文章 0 订阅
1 篇文章 0 订阅

文章目录

介绍

一、直接插入排序

1.排序过程

 2.代码实现

二、折半插入排序

1.排序过程

2.代码实现

三、希尔排序

1.排序过程

2.代码实现

四、冒泡排序

1.排序过程

2.代码实现

五、简单选择排序

1.排序过程

2.代码实现

六、快速排序(分治法)

1.排序过程

2.代码实现

总结


介绍

本人目前正处于考研备考中,在这里整理了数据结构常考的六种排序算法,希望对同数据结构考研的宝子们也有所帮助。

一、直接插入排序

1.排序过程

  1. 从第二个元素开始,将当前元素视为要插入的值。
  2. 将当前元素与前一个已经排好序的元素进行比较。
  3. 如果前一个元素大于当前元素,将前一个元素向后移动一位,腾出位置给当前元素。
  4. 重复步骤 3,直到找到合适的位置插入当前元素,或者到达数组的开头。
  5. 将当前元素插入到合适的位置。
  6. 重复步骤 1 到 5,直到所有元素都被插入到合适的位置。

 2.代码实现

//1.直接插入排序(n为待排序元素的个数)
void DirectInsertSort(ElemType a[], int n) {
    ElemType temp;  //用于存储待插入元素
    for (int i = 1; i < n; ++i) { //遍历a[1]-a[n-1]
        if (a[i] < a[i - 1]) {
            temp = a[i];  //将小于直接前驱的元素存入到保留到temp
            //向前寻找比temp大的元素并依次后移
            int j;
            for (j = i - 1; j >= 0 && a[j] > temp; --j) {  
                a[j + 1] = a[j];
            }
            a[j + 1] = temp;
        }
    }
}


//主函数
int main() {
    int a[] = {12, 6, 3, 56, 2, 24, 18};
    DirectInsertSort(a, 7);
    for (int i = 0; i < 7; ++i) {
        printf("%d ", a[i]);
    }
}

二、折半插入排序

1.排序过程

  1. 从第二个元素开始,将当前元素视为要插入的值。
  2. 利用二分查找在已经排好序的部分序列中找到合适的插入位置。
  3. 将当前元素插入到找到的合适位置。
  4. 重复步骤 1 到 3,直到所有元素都被插入到合适的位置。

2.代码实现

//2.折半插入排序
void HalfInsertSort(ElemType a[], int n) {
    int low, high, mid;
    ElemType temp;  //用于存储待插入元素

    //采用折半查找找出元素的插入位置
    for (int i = 1; i < n; ++i) {
        if (a[i] < a[i - 1]) {
            temp = a[i];

            //当前元素的左半部分折半查找
            low = 0;
            high = i - 1;
            while (low <= high) {
                mid = (low + high) / 2;
                if (a[mid] > temp) {
                    high = mid - 1;
                } else {
                    low = mid + 1;  //包含了low=high的情况,保证了算法的稳定性
                }
            }

            //后移元素
            int j;
            for (j = i - 1; j >= high + 1; j--) {
                a[j + 1] = a[j];
            }
            //插入元素
            a[j + 1] = temp;  //(或a[high+1]=temp)
        }
    }
}

//主函数
int main() {
    int a[] = {12, 6, 3, 56, 2, 24, 18};
    HalfInsertSort(a, 7);
    for (int i = 0; i < 7; ++i) {
        printf("%d ", a[i]);
    }
}

三、希尔排序

1.排序过程

  1. 选择一个增量序列,通常是一系列递减的正整数。常用的增量序列有希尔增量、Hibbard增量等。
  2. 根据选定的增量,将数组分成多个子序列,每个子序列包含间隔为增量的元素。
  3. 对每个子序列进行插入排序,将子序列中的元素逐步移动到正确的位置。
  4. 逐步减小增量,重复步骤 2 和 3,直到增量减至1。
  5. 最后进行一次增量为1的插入排序,完成整个排序过程。

2.代码实现

//3.希尔排序
void XierSort(ElemType a[], int n) {
    int dk; //排序增量
    ElemType temp;  //用于存储待插入元素
    //排序增量每次减半
    for (dk = n / 2; dk >= 1; dk = dk / 2) {
        for (int i = dk; i < n; ++i) {
            if (a[i] < a[i - dk]) {
                temp = a[i];
                //依次后移元素
                int j;
                for (j = i - dk; j >= 0 && a[j] > temp; j = j - dk) {
                    a[j + dk] = a[j];
                }
                //插入元素
                a[j + dk] = temp;
            }
        }
    }
}

//主函数
int main() {
    int a[] = {12, 6, 3, 56, 2, 24, 18};
    XierSort(a, 7);
    for (int i = 0; i < 7; ++i) {
        printf("%d ", a[i]);
    }
}

四、冒泡排序

1.排序过程

  1. 从数组的最后一个元素开始,依次比较相邻的两个元素。
  2. 如果前一个元素大于后一个元素,就交换这两个元素的位置。
  3. 继续重复步骤 1 和 2,直到第一个元素。这样一轮过去后,数组的最小元素就会“冒泡”到数组的开头。
  4. 接下来,将数组的范围缩小一个元素,重复步骤 1 到 3。这样进行多轮,直到整个数组有序。
  5. 如果某趟排序中一次元素交换都没有发生,则说明已经有序,可以提前结束,提高效率。

2.代码实现

//4.冒泡排序
void BubbleSort(ElemType a[], int n) {
    for (int i = 0; i < n; ++i) {
        int flag = 0; //标志本趟排序是否发生交换
        for (int j = n - 1; j > i; --j) {
            if (a[j] < a[j - 1]) {
                //交换位置
                ElemType temp = a[j];
                a[j] = a[j - 1];
                a[j - 1] = temp;
                flag = 1;
            }
        }

        //一趟排序过后如果一次交换都没有发生,则已经有序
        if (flag == 0) {
            return;
        }

    }
}

//主函数
int main() {
    int a[] = {12, 6, 3, 56, 2, 24, 18};
    BubbleSort(a, 7);
    for (int i = 0; i < 7; ++i) {
        printf("%d ", a[i]);
    }
}

五、简单选择排序

1.排序过程

  1. 首先,找到数组中最小的元素,将其与第一个元素交换位置,这样最小的元素就排在了正确的位置上。
  2. 接着,在剩余的未排序部分中,找到最小的元素,将其与第二个元素交换位置,这样前两个元素都已经排好序了。
  3. 依此类推,在每一轮选择过程中,选择未排序部分中的最小元素,将其交换到已排序部分的末尾,直到所有元素都被放到正确的位置为止。

2.代码实现

//5.简单选择排序
void SimpleSelectSort(ElemType a[], int n) {
    for (int i = 0; i < n - 1; ++i) {  //n-1趟排序,每次选出一个最下元素
        int min = i;

        //查找最小元素的位置
        for (int j = i + 1; j < n; ++j) {
            if (a[j] < a[min]) {
                min = j;
            }
        }
        //判断min的位置是否改变,如果改变则交换
        if (min != i) {
            ElemType temp = a[min];
            a[min] = a[i];
            a[i] = temp;
        }
    }
}

//主函数
int main() {
    int a[] = {12, 6, 3, 56, 2, 24, 18};
    SimpleSelectSort(a, 7);
    for (int i = 0; i < 7; ++i) {
        printf("%d ", a[i]);
    }
}

六、快速排序(分治法)

1.排序过程

  1. 选择一个基准元素(通常是数组的第一个元素)。
  2. 将数组中比基准元素小的元素移到基准元素的左边,比基准元素大的元素移到右边。这个过程称为分区(Partition)。
  3. 对基准元素左边的子数组和右边的子数组分别递归地进行快速排序。
  4. 重复步骤 2 和 3,直到子数组的大小为 1 或 0,此时子数组已经有序。

2.代码实现

//6.快速排序
int Partition(ElemType a[], int low, int high) {
    ElemType p = a[low]; //将当前表中第一个元素设置为枢轴
    while (low < high) {
        //依次向左找到比枢轴元素小的元素
        while (low < high && a[high] >= p) {
            high--;
        }
        a[low] = a[high];
        //依次向右找到比枢轴元素大的元素
        while (low < high && a[low] <= p) {
            low++;
        }
        a[high] = a[low];
    }
    //插入枢轴元素
    a[low] = p;
    return low;
}

void QuickSort(ElemType a[], int low, int high) {
    if (low < high) {
        //对表进行划分
        int p = Partition(a, low, high);
        //递归排序左子表
        QuickSort(a, low, p - 1);
        //递归排序右子表
        QuickSort(a, p + 1, high);
    }
}

//主函数
int main() {
    int a[] = {12, 6, 3, 56, 2, 24, 18};
    QuickSort(a, 0,6);
    for (int i = 0; i < 7; ++i) {
        printf("%d ", a[i]);
    }
}

总结

头一次写博客,如有错误,请大家指正!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值