排序有哪些方法?

luoviking 2009-12-23 12:10:33
书上讲过的只有冒泡法和选择排序法,请问还有其他的吗???
有的话给简单的讲下吧```
...全文
397 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
http://www.cppblog.com/shongbee2/archive/2009/04/25/81058.html


建议你照本数据结构书,或者算法导论,把8大排序都自己实现一遍。

随便贴点例子给你吧。

堆排序:


void sift(int e[]/*存储结点序列*/,
int n/*序列的结点个数*/,
int s/*对e[s]做渗透,其中e[s]的左右子树是堆*/)
{
int t,k,j;
t=e[s];
k=s;
j=2*k+1;/*e[k]是e[j]和e[j+1]的父结点*/
while(j<n)/*为渗透到页结点*/
{
if(j<n-1 && e[j]<e[j+1])//j<n-1??,e[j]<e[j+1]又是比较什么? 选出是左子还是右子跟父接点比较
j++; /*e[j+1]是e[k]较大的子结点*/
if(t<e[j])/*改连续渗透交换为循环传送*/
{// 交换每个父接点与子接点,满足大顶堆,同时继续比较子接点
e[k]=e[j];
k=j;
j=2*k+1;
printf("t:%d\n",t);
}
else
break;/*已是一个堆*/
}
e[k]=t;
}

void heapsort(int e[],int n)
{
int i,k,t;
for(i=n/2-1;i>=0;i--)// 从最后一个非叶子节点开始建堆
sift(e,n,i);/*建初始堆*/
for(k=n-1;k>=1;k--)
{
t=e[0];/*根结点与堆的末结点交换*/
e[0]=e[k];
e[k]=t;
printf("e[%d]:%d\n",k,t);
sift(e,k,0);/*重新建堆*/
}
}

void main()
{
int i,e[10]={93,35,29,45,48,82,76,17,11,33};
heapsort(e,10);
for(i=0;i<=9;i++)
printf("%4d",e[i]);
}



快速排序:



const int NUM=20;

int arr[] = {1,10,11,5,6,15,0,15,16,14,0,8,17,15,7,19,17,1,18,7};

/* swap函数:交换v[k]与v[j]的值 */
inline void swap(int v[], int k, int j)
{
int temp;
temp = v[k];
v[k] = v[j];
v[j] = temp;
}

void qsort(int v[], int left, int right)
{
int j, left_c,right_c,sigh;
left_c=left; //当前一趟快排的最左序号
right_c=right; //当前一趟快排的最右序号
sigh=0; //0表示从左边开始排
while(left_c!=right_c)
{
if(v[left_c]<v[right_c]) //搜索可以交换的位置
{
if(sigh==0)
--right_c;
else
++left_c;
continue;
}
if(sigh==0) //小头有空,交换
{
swap(v,left_c++,right_c);
sigh=1;
}
else //大头有空,交换
{
swap(v,left_c,right_c--);
sigh=0;
}
}
for(j=0;j<NUM;++j)
cout<<v[j]<<" ";
cout<<endl;
/*一次快排结束,小头和大头继续搜索*/
if(left<left_c-1)
qsort(v, left, left_c-1);
if(right>right_c+1)
qsort(v, right_c+1, right);
}

void main()
{
int j;
qsort(arr, 0, NUM-1);
for(j=0; j<NUM; j++)
printf("%d ", arr[j]);
printf("\n");
}



归并排序:



const int NUM=20;



int arr[] = {1,10,11,5,6,15,0,15,16,14,0,8,17,15,7,19,17,1,18,7};

void merge(int v[],int left,int mid,int right) //合并[left,mid]和[mid+1,right]
{
int i,j,k=0;
i=left; //i为第一路的下标
j=mid+1; //j为第二路的下标
int *temp=new int[right-left+1];
while(i<=mid&&j<=right)
temp[k++]=(v[i]<=v[j])?v[i++]:v[j++]; //依次合并2路到temp数组
while(i<=mid)
temp[k++]=v[i++];
while(j<=right)
temp[k++]=v[j++];
for(i=left,j=0;i<=right;++i,++j) //合并完数据写回v数组
v[i]=temp[j];
delete []temp;
}

void merge_sort(int v[],int num)
{
int i,size,j,mid,right;
for(i=1;i<num;i*=2) //log(n)趟归并
{
size=i-1;
j=0;
while(j<num)
{
mid=j+size;
right=j+2*size+1;
if(mid>=num) //下标不能溢出
mid=num-1;
if(right>=num)
right=num-1;
merge(v,j,mid,right);
j=right+1;
}
}
}

void main()
{
int j;
merge_sort(arr, NUM);
for(j=0; j<NUM; j++)
printf("%d ", arr[j]);
printf("\n");
}





插入排序:


void insert_swap(int *ele,int n)
{
int i,j,sem,var;
for(i=1;i<n;i++)
{
j=i;
sem=0;
while(sem==0)
{
if(*(ele+j)<*(ele+j-1))
{
var=*(ele+j);
*(ele+j)=*(ele+j-1);
*(ele+j-1)=var;
j--;
if(j==0)
{
sem++;
}
}
else if(*(ele+j)>=*(ele+j-1))
{
sem++;
// printf("no finding stop sem\n");
}
}
}

}

void main()
{
int i;
int element[10]={77,91,53,56,80,34,67,0,88,34};
insert_swap(element,10);
for(i=0;i<10;i++)
{
printf("element[%d] is %d\n",i+1,element[i]);
}
}




其他的像冒泡这种就不贴了。
Inhibitory 2009-12-23
  • 打赏
  • 举报
回复
1. 内部排序
插入方式排序:直接插入排序,折半插入排序,二路插入排序,表插入排序,希尔排序
起泡方式排序:冒泡排序,快速排序。
选择方式排序:选择排序,堆排序。
归并排序。
基数排序。

2. 外部排序
都是使用归并的方式来进行排序。
mmilmf 2009-12-23
  • 打赏
  • 举报
回复
插入排序, 又分为直接插入排序和折半插入排序。
快速排序,堆排序,希尔排序,归并排序以及基序排序等
在网上搜一下吧,这些算法都有的

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧