排序算法问题(一)直接选择排序,冒泡排序,插入排序,快速排序,归并排序
堆排序
核心思想:
堆:
1.完全二叉树。
2.父节点大于子节点。
用一维数组表示完全二叉树,因此数列如果不满足父节点大于子节点就需要调整,从倒数第二行开始往前整理。
排序:
将堆中的根节点与最后一个节点位置交换,再砍断最后一个节点,得到的数即为最大值,再将剩下的数重新整理为堆,再重复操作。
For instance:
上源码:
#include<stdio.h>
#define N 5
void swap(int arr[],int i,int j)
{
int temp;
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
//调整父节点大于子节点
void heapify(int tree[],int n,int i)
{
int c1,c2,max;
c1 = 2*i+1;//左孩子节点
c2 =2*i+2;//右孩子节点
max =i;//根节点
if(i>=n)//递归出口
return;
if(c1<n&&tree[c1]>tree[i])
max =c1;
if(c2<n&&tree[c2]>tree[max])
max = c2;
if(max!=i)//如果根节点不是最大
{
swap(tree,max,i);//交换根节点与子节点的值
heapify(tree,n,max);//子节点作为父节点再与他的字节点比较
}
}
//当数较乱时,建立堆使根节点大于子节点
void build_heap(int tree[],int n)
{
int last_node = n-1;//从后往前
int parent = (last_node-1)/2;//父亲节点
int i;
for(i = parent;i>=0;i--)
{
heapify(tree,n,i);
}
}
void heep_sort(int tree[],int n)
{
int i;
build_heap(tree,n);//保证为堆
for(i=n-1;i>=0;i--)
{
swap(tree,i,0);//将根节点和最后一个节点交换
heapify(tree,i,0);//舍弃最后一个节点,因为它已经是最大
}
}
int main(){
int tree[N];
int n=N,i;
printf("请输入%d个整数:\n",n);
for(i=0;i<N;i++)
scanf("%d",&tree[i]);
heep_sort(tree,n);
for(i=0;i<N;i++)
printf("%d ",tree[i]);
putchar('\n');
return 0;
}
希尔排序
核心思想:
1.希尔排序是对插入排序的改进。
2.插入排序在数据元素比较少,或者数据元素基本有序时,算法效率高。
3.因此在数据元素比较大,元素又无序时,可以先将数据整理成基本有序,再最后用一次插入排序。
将待排数据分成若干子序列(将间隔一定距离的数据组成一个序列,然后不断缩小距离组成数列(比如刚开始的子序列的位置为1,5,9…&&2,6,10…&&…下次分组为1,3,5…&&2,4,6&&…)),分别进行插入排序,待整体数据基本有序时,再对整体数据进行一次插入排序。
上源码:
#include <stdio.h>
#define N 10
void shell_sort(int array[], int length){
int i,j,k;
int gap; //gap是分组的步长
int temp; //暂存数据
for(gap=length/2; gap>0; gap=gap/2)
{//逐渐减小间距
for(i=0; i<gap; i++)
{//将数据分组
for(j=i+gap; j<length; j=j+gap)//每组数据进行插入排序
{ //单独一次的插入排序
temp=array[j];
for(k=j;k>=0&&temp<array[k-gap];k=k-gap)
{
array[k]=array[k-gap];
}
array[k]=temp;
}
//下面注释代码为while循环实现内层for循环效果
/*if(array[j] < array[j - gap])
{
temp = array[j]; //将位置j的数据取出
k = j - gap;//记录j元素之前的元素位置
while(k>=0 && array[k]>temp)//改组中将前面比j位置大的数据往后移
{
array[k + gap] = array[k];
k = k - gap;
}
array[k + gap] = temp;//将j位置插到合适的位置
}
*/
}
}
}
int main()
{
int arr[N],i,x;
x=N;
printf("请输入 %d 个数据:\n",x);
for(i=0;i<N;i++)
scanf("%d",&arr[i]);
shell_sort(arr, N);
printf("排序后的顺序是:\n");
for(i=0;i<N;i++)
printf("%5d",arr[i]);
printf("\n");
return 0;
}