三、排序算法

所有例子都是升序排序。
数据分成两部分:已排序和待排序。

排序过程中,数据移动分为两种:
1. 直接移动:移动数据的存储位置,消耗时间
2. 逻辑移动:改变指向这些数据的指针

选择排序

特点:遍历待排序数据,把最小值与起始数据(最左边)交换位置
次数:第一轮n-1次,第k轮n-k次
步骤:
1. 如果待排序数据大于0,则循环2,3
2. 从待排序的数据取第一个值data[i](前面的i-1个数据已经排好了)
3. 如果data[i]>data[i+n]则交换(即从待排序的数据中找到最小值,放到i那个位置上)

char temp;
char data[5]={ 2, 7, 4, 0, 6 };
int n = sizeof(data);

for(int i=0; i<n; i++) {
for(int j=i+1; j<n; ++) {
if(data[i] > data[j]) {
temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
}

冒泡排序(交换排序)

特点:从左边开始,对比相邻两个数据,根据大小调整顺序,慢慢把比较大的数移动到右边
次数:第一轮n-1次,第k轮n-k次
步骤:
1. 如果待排序数据大于0,则循环2,3
2. 从待排序的数据取第一个值data[i]和data[i+1]
3. 如果data[i]>data[i+1]则交换,把正在比较的值向后移动一位(右边是已排序部分)

char temp;
char data[5]={ 2, 7, 4, 0, 6 };
int n = sizeof(data);

for(int i=n-1; i>=0; i–) {
for(int j=0; j<=i-1; j++) {
if(data[j] > data[j+1]) {
temp = data[j];
data[j] = data[j+1];
data[j+1] = temp;
}
}
}

桶排序

特点:简单,需要很大的数组
步骤:
1. 定义数组,初始值为0
2. 从待排序的数据取值,数组中对应下标的数据加1
3. 把数组的下标的值取出来

char temp[8]={0};
char data[5]={ 2, 7, 4, 0, 6 };
int n = sizeof(data);

for(int i=0; i<n; i++) {
temp[data[i]] +=1;
}
int index=0;
for(int i=0; i<8; i++) {
while(temp[i] > 0) {
data[index++]=temp[i];
temp[i] -=1;
}
}

插入排序

特点:把未排序数据取出,插入已排序的数据的响应位置
步骤:
1. 从待排序的数据中取出一个
2. 从右往左与已排序的数据比较,如果小于,则继续比较,直到大于时,确定插入位置
3. 已排序的数据中,插入位置右边的数据要整体右移一位
4. 数据插入指定位置
或者
1. 从待排序的数据中取出一个
2. 向左边的数据比较,如果小于,交换,直到大于时

char data[5]={ 2, 7, 4, 0, 6 };
int n = sizeof(data);

for(int i=i; i<n-1; i++) {
for(int j=i-1; j>=0; i–) {
if(data[i] > data[j]) {
temp = data[i];
for(int k=i; k>=j+1; k–) {
data[k]=data[k-1];
}
data[j] = temp;
break;
}
}
}

快速排序

特点:未排序数据中任选一个基准数据,以数据为分割点,小于基准的放左边,大基准的放右边。再对基准两边是数据进行同样的操作,直到只剩下一个数。(其实是使用递归)
步骤:
1. 选取基准点
2. 小于放左边,大于放右边
3. 一直到分组后,每组只有一位
4. 从左向右找ki,使得ki>k
5. 从右向左找kj,使得kj<k
6. 如果i<j,或换
7. 如果i>=j,k和kj互换,并已j为基准点分割成两部分,对左右两边排序,直到左半边的值等于右半边

希尔排序

特点:把目标数据分成几个区域,再对区块内的数据进行插入排序,再减少间隔。适用于大部分已经排好序的数据
步骤:
1. 数据之间的间隔是n/2,第1个和第n/2+1个进行插入排序,第2个和第n/2+2个进行插入排序,以此类推
2. 数据之间的间隔是n/4,第1个、n/4+1, 2n/4, 3n/4个进行插入排序,以此类推
3. 循环直到间隔为1

归并排序

特点:把数据分割为更小的部分进行排序,再把排序好的数据合并
步骤:
1. 将N个长度为1的键值成对合并成N/2个长度为2的键值组
2. 成对合并成N/4个长度为4的键值组
3. 一直到N个长度为1的键值

基数排序法

不进行元素之间的直接比较,按比较方向分为最高位优先msd和最低位优先lsd。msd从最左边的位数开始比较

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值