所有代码经过调试可以运行,只是自己的一些简单想法的总结,希望大家能多多批评谢谢!!!
所使用到的头文件
#include<stdio.h>
#define MAXSIZE 100
typedef int keytype;
typedef struct{
keytype key;
int other;
}recordtype;
typedef struct{
recordtype r[MAXSIZE+1];//待排序数组
int length;
}table;
插入排序
直接插入排序
//插入排序最难理解的在哨兵的选取和位置的移动,将第一个元素默认为已排好序的元素放在中括号中,
比较从第二个元素开始,每进行一次比较哨兵的位置就从第一个元素后移,直到元素为空。
void insertsort(talbe *tab)
{
int i,j;
for(i=2;i<=table->length;i++)
{
j=i-1;
tab->r[0]=tab->r[i];
while(tab->r[0].key<tab->r[j].key)
{
tab->r[j+1]=tan->r[j];
j=j-1;
}
tab->r[j+1]=tab->r[0];
}
}
二分插入排序
//二分的思想是在将元素逐渐进入中括号的时候随着元素的增加,在查找相应的元素的位置时,使用
二分查找,简称二分插入排序。
void binarysort(table *tab)
{
int i,j,left,right,mid;
for(i=2;i<=tab->length;i++)
{
tab->r[0]=tab->r[i];
left=1;right=i-1;
while(left<=right)
{
mid=(left+right)/2;
if(tab->r[i].keyr[mid].key)
right=mid-1;
else
left=mid+1;
}
for(j=i-1;j>=left;j–)
tab->r[j+1]=tab->r[j];
tab->r[left]=tab->r[0];
}
}
选择排序
//直接选择排序是将一个序列的第一个元素作为最小(最大)元素,再定义一个j,用于移动到接下来的每一个元素,来与第一个元素进行比较,找到最大或者最小的元素便交换位置,以此类推。
void selectsort(table *tab)
{
int i,j,k;
for(i=1;i<=tab->length;i++)
{
k=i;
for(j=i+1;j<=tab->length;j++)
{
if(tab->r[j].key<tab->r[k].key) k=j;
}
if(k!=i)
{
tab->r[0]=tab->r[k];
tab->r[k]=tab->r[i];
tab->r[i]=tab->r[0];
}
}
}
//树形选择排序思想 一组排序码,两两进行比较,选出最大值,就像二叉树,两个叶子节点进行比较选出的最大值就是一颗子数的树根,依次进行下去,排序好的元素在其原来位置用正无穷大代替。如果带排序序列为奇数个,则增加一个正无穷大(或者比所有排序序列大的元素作为节点插入)。
//堆排序原理可以用二叉树表示,二叉树的根便是待排序元素中最小(最大)的元素,依次进行比较直到所 有元素均进入二叉树(分为小根堆和大根堆)。
void sift(table *tab,int k,int m) //筛选算法,将任意一个排序码序列建成堆。
{
int i,j,finished;
i=k;j=2*i;tab->r[0]=tab->r[k];finished=0;
while((j<=m)&&(!finished))
{
if((j<m)&&(tab->r[j+1].key<tab->r[i].key)) j++;
if(tab->r[0].key<=tab->r[j].key) finished=1;
else
{
tab->r[i]=tab->r[j];
i=j;j=2*j;
}
}
tab->r[i]=tab->r[0];
}
void heapsort(table *tab)
{
int i;
for(i=tab->length/2;i>=1;i--) sift(tab,i,tab->length); //建堆
for(i=tab->length;i>=2;i--) //i表示当前等待排序的元素的多少
{
tab->r[0]=tab->r[i];
tab->r[i]=tab->r[1];
tab->r[1]=tab->r[0]; //以上三个语句是将堆中最小的元素与最后一个元素进行交换。
}
}
交换排序
//冒泡排序就是一个待排序序列两两之间进行比较如果符合条件就进行交换,通常要进行多次交换。
void bubblesort(table *tab)
{
int i,j,done;
i=1;done=1;
while(i<=tab->length && done)
{
done=0;
for(j=1;j<=tab->length-i;j++) //每次进行比较结束后总的比较长度就减小1;
if(tab->r[j+1].key<tab->r[j].key)
{
tab->r[0]=tab->r[j];
tab->r[j]=tab->r[j+1];
tab->r[j+1]=tab->r[0];
}
i++;
}
}
//快速排序主要运用递归进行运算,首先选取一个标志元素将其放在其最终排序完应该放置的位置,然后对剩下的元素进行排序,做到标志元素之前的元素都不大于它,标记元素之后的元素都不小于它,依次对前后两部分进行递归调用。(在放置元素时不大于x的元素从第一个位置开始由左向右进行放置,将大于x的元素从最后一个位置由右向左顺序放置)。
void quicksort(table *tab,int left,int right)
{
int i,j;
if(left<right)
{
i=left;j=right;
tab->r[0]=tab->r[i];
do
{
while(i<j && tab->r[j].key>tab->r[0].key) j--;
if(i<j)
{
tab->r[i].key=tab->r[j].key;
i++;
}
while(i<j && tab->r[i].key>tab->r[0].key) i++;
if(i<j)
{
tab->r[j].key=tab->r[i].key;
j--;
}
}while(i!=j);
tab->r[i]=tab->r[0];
quicksort(tab,left,i-1);
quicksort(tab,i+1,right);
}
}
//归并排序简单而言就是对一组待排序数组每次按照len的长度分组,将相邻两个分组进行排序合并为一个数组,进行完毕后从len/2变为len/4,称为一趟归并,依次进行进行排序,直到有序段长度不小于待排序文件长度,排序完成。