当前位置:首页 » 编程语言 » 数据结构排序c语言

数据结构排序c语言

发布时间: 2023-08-23 04:14:21

c语言数据结构中的几种内部排序法,求解!高手速度来指导我。。

1.Shell排序(ShellSort)

Shell排序通过将数据分成不同的组,先对每一组进行排序,然后再对所有的元素进行一次插入排序,以减少数据交换和移动的次数。平均效率是O(nlogn)。其中分组的合理性会对算法产生重要的影响。现在多用D.E.Knuth的分组方法。

Shell排序比冒泡排序快5倍,比插入排序大致快2倍。Shell排序比起QuickSort,MergeSort,HeapSort慢很多。但是它相对比较简单,它适合于数据量在5000以下并且速度并不是特别重要的场合。它对于数据量较小的数列重复排序是非常好的。

2.快速排序(QuickSort)

快速排序是一个就地排序,分而治之,大规模递归的算法。从本质上来说,它是归并排序的就地版本。快速排序可以由下面四步组成。

(1) 如果不多于1个数据,直接返回。

(2) 一般选择序列最左边的值作为支点数据。

(3) 将序列分成2部分,一部分都大于支点数据,另外一部分都小于支点数据。

(4) 对两边利用递归排序数列。

快速排序比大部分排序算法都要快。尽管我们可以在某些特殊的情况下写出比快速排序快的算法,但是就通常情况而言,没有比它更快的了。快速排序是递归的,对于内存非常有限的机器来说,它不是一个好的选择。

3堆排序(HeapSort)

堆排序适合于数据量非常大的场合(百万数据)。

堆排序不需要大量的递归或者多维的暂存数组。这对于数据量非常巨大的序列是合适的。比如超过数百万条记录,因为快速排序,归并排序都使用递归来设计算法,在数据量非常大的时候,可能会发生堆栈溢出错误。

堆排序会将所有的数据建成一个堆,最大的数据在堆顶,然后将堆顶数据和序列的最后一个数据交换。接下来再次重建堆,交换数据,依次下去,就可以排序所有的数据。

下面是一个总的表格(这张表很重要),大致总结了我们常见的所有的排序算法的特点。
排序法 平均时间 最差情形 稳定度 额外空间 备注
冒泡 O(n2) O(n2) 稳定 O(1) n小时较好
交换 O(n2) O(n2) 不稳定 O(1) n小时较好
选择 O(n2) O(n2) 不稳定 O(1) n小时较好
插入 O(n2) O(n2) 稳定 O(1) 大部分已排序时较好
基数 O(logRB) O(logRB) 稳定 O(n)
B是真数(0-9),

R是基数(个十百)

Shell O(nlogn) O(ns) 1<s<2 不稳定 O(1) s是所选分组
快速 O(nlogn) O(n2) 不稳定 O(nlogn) n大时较好
归并 O(nlogn) O(nlogn) 稳定 O(1) n大时较好
堆 O(nlogn) O(nlogn) 不稳定 O(1) n大时较好
备注:O(n2)表示双重循环,即n^2

❷ 数据结构C语言--三种以上的排序算法

快速排序:
void QSort(int a[], int l, int r) //单关键字交换法快排
{
int i = l, j = r, mid = (i + j) / 2; //二分[i,j]区间

while (i <= j) //让a[mid]左边都比a[mid]小,右边都比a[mid]大
{
while (a[i] < a[mid]) //找到一个元素a[i]比a[mid]小
i++;
while (a[j] > a[mid]) //找到一个元素a[j]比a[mid]大
j--;
if (i <= j) //交换a[i]和a[j],并让指针向中间靠拢
Swap(a[i++], a[j--]);
}

if (i < r)
QSort(a, i, r); //对右区间[i,r]递归排序
if (l < j)
QSort(a, l, j); //对左区间[l,j]递归排序
}

归并排序:
void Merge(int a[], int l, int m, int r) //将a中区间[l, r]合并为有序
{
int x[101], y[101]; //循环变量
int i, j, k;
int l1 = m - l + 1, l2 = r - m; //l1表示区间[l, m]的长度,l2表示区间[m + 1, r]的长度

for (i = 1; i <= l1; i++) //将a中区间[l, m]复制到x中
{
x[i] = a[l + i - 1];
}

for (i = 1; i <= l2; i++) //将a中区间[m + 1, r]复制到y中
{
y[i] = a[m + i];
}

x[l1 + 1] = MaxInt; //设置一个很大的数作为结束标志
y[l2 + 1] = MaxInt;
i = 1;
j = 1;

for (k = l; k <= r; k++) //将两个区间合并成为一个有序区间
{
if (x[i] <= y[j])
{
a[k] = x[i++];
}
else
{
a[k] = y[j++];
}
}
}

void MergeSort(int a[], int l, int r) //对a数组的[l, r]区间排序
{
int m;

if (l < r)
{
m = (l + r) / 2; //二分区间[l, r]

MergeSort(a, l, m); //递归二分区间[l, m]
MergeSort(a, m + 1, r); //递归二分区间[m + 1, r]

Merge(a, l, m, r); //合并区间[l, m]和[m + 1, r]
}
}

二叉排序树排序:
struct BinaryTree //二叉树结构
{
int data, p, l, r; //data数值域,p父节点编号,l左儿子编号,r右儿子编号
};

int root = 0;

void Init(BinaryTree a[], int &n) //读入数据域,并初始化树
{
cin >> n;

for (int i = 1; i <= n; i++)
{
cin >> a[i].data;
a[i].p = a[i].l = a[i].r = -1;
}
}

void Insert(BinaryTree a[], int i) //在二叉查找树中插入编号为 i 的节点
{
int parent = -1, x = a[1].p; //parent 始终指向 x 的父节点编号

while (x != -1) //向下搜索,直到找到最下一层
{
parent = x;
if (a[i].data < a[x].data)
x = a[x].l;
else
x = a[x].r;
}

a[i].p = parent; //把第 i 号节点的父亲指向parent
if (parent != -1) //判断树是否为空
{
if (a[i].data < a[parent].data) //向父节点插入儿子
a[parent].l = i;
else
a[parent].r = i;
}
else //为空就以 i 节点为根节点
a[root].p = i;
}

void BuildTree(BinaryTree a[], int n) //建立二叉查找树
{
root = 1;
for (int i = 1; i <= n; i++) //依次插入 n 个节点到二叉查找树
{
Insert(a, i);
}
a[root].p = -1;
}

void Sort(BinaryTree a[], int i) //中序遍历输出
{
if (a[i].l > -1) //递归遍历左儿子
Sort(a, a[i].l);
cout << a[i].data << " "; //输出节点
if (a[i].r > -1) //递归遍历右儿子
Sort(a, a[i].r);
}

堆排序:
void Heap(int a[], int n, int p) //维护最大(最小)堆,维护以P为根的堆
{
int l = p * 2, r = l + 1, t = p; //左儿子编号为2P,右儿子为2P+1,初始化根节点P为最大

if ((l <= n) && (a[l] > a[p])) //找一个最大的数,维护最大堆(改为<就是维护最小堆)
t = l;
if ((r <= n) && (a[r] > a[t])) //找一个最大的数,维护最大堆(改为<就是维护最小堆)
t = r;
if (p != t) //如果根节点不是最大,和最大的交换,再递归维护堆
{
Swap(a[p], a[t]);
Heap(a, n, t);
}
}

void HeapSort(int a[], int n)
{
int i;

for (i = n / 2; i >= 1; i--) //n / 2开始必然是根节点,依次调用Heap,建立一个最大堆
Heap(a, n, i);

for (i = n; i >= 2; i--) //每次将堆顶和当前堆最后一个节点(i)交换,然后将[1, i - 1]重新堆化
{
Swap(a[i], a[1]);
Heap(a, i - 1, 1);
}
}

插入排序:
void InsertionSort(int a[], int l, int r) //对区间[l, r]执行插入排序
{
int i, j, t;

for (i = l + 1; i <= r; i++)
{
j = i - 1;
t = a[i];

while ((j >= l) && (a[j] > t)) //后移操作,并找到正确的位置
{
a[j + 1] = a[j];
j--;
}

a[j + 1] = t;
}
}

以上所有的Swap函数的意思都是交换两个变量。

❸ 在数据结构中用c语言怎么编写用单链表将26个字母排序的程序

#include <stdio.h>
#include <stdlib.h>

//申明链表
typedef struct node
{
char num;
struct node *next;
}list;

void Bubble_sort(list *L);//链表的冒泡排序
void Dis_list(list *L);//遍历单链表

int main()
{
//建表
list *r,*s,*p;
int n=26;//存储数据的个数
s=NULL;
for(int i='Z';i>='A';i--)
{
r=(list *)malloc(sizeof(list));
r->num = i;
if(!s){s=r;p=s;}
p->next=r;
p=r;
}
p->next=NULL;
printf("排序前:\t");
Dis_list(s);
//排序
Bubble_sort(s);
printf("排序后:\t");
Dis_list(s);
return 0;
}

void Dis_list(list *L)
{
list *r;
r=L;
while(r!=NULL)
{
printf("%c\t",r->num);
r=r->next;
}
printf("\n");
}

void Bubble_sort(list *L)
{
list *r,*s;
char temp;
for(r=L;r;r=r->next)
{
for(s=r;s;s=s->next)
{
if(r->num>s->num)
{
temp=r->num;
r->num=s->num;
s->num=temp;
}
}
}
}

❹ C语言中结构体数据排序

设结构体名为AAA,结构体数组声明为struct AAA a[N];(N为宏定义常量),身份证成员名为id,则排序函数可如下写——

#include"stdio.h"
#include<string.h>
#defineN3
structAAA{
charid[20];
intage;
};
voidmysort(structAAA*p){//排序函数
structAAAt;
inti,j,k;
for(i=0;i<N;i++){
for(k=i,j=k+1;j<N;j++)
if(strcmp((p+j)->id,(p+k)->id)<0)
k=j;
if(i!=k)
t=*(p+k),*(p+k)=*(p+i),*(p+i)=t;
}
}
intmain(intargc,char*argv[]){//测试主函数
structAAAa[N]={{"650104194812109907",77},{"333018201801015555",1},{"650104194812109903",80}};
mysort(a);
printf("%s %d ",a[0].id,a[0].age);
printf("%s %d ",a[1].id,a[1].age);
printf("%s %d ",a[2].id,a[2].age);
return0;
}

运行结果:

❺ 输入一组整数对该序列进行简单选择和归并排序(数据结构用c语言写啊)

给你一个归并排序的具体算法和分析:
两路归并排序算法思路:
①.
把n个记录看成n个长度为l的有序子表
;
②.
进行两两归并使记录关键字有序,得到n/2个长度为2的有序子表;
③.
重复第②步直到所有记录归并成一个长度为n的有序表为止;
具体算法:
//
归并操作
template
static
void
merge
(typearray[],
int
p,
int
q,
int
r){
int
i
,
k
;
int
begin1
,
end1
,
begin2
,
end2
;
int*
temp
=
(int*)malloc((r-p)*sizeof(int))
;
begin1
=
p
;
end1
=
q
;
begin2
=
q+1
;
end2
=
r
;
k
=
0
;
while
(begin1
<=
end1
&&
begin2
<=
end2){
if
(array[begin1]
<
array[begin2]){
temp[k]
=
array[begin1]
;
begin1
++
;
}
else{
temp[k]
=
array[begin2]
;
begin2
++
;
}
k
++
;
}
while
(begin1
<
end1)
temp[k++]
=
array[begin1++]
;
while
(begin2
<
end2)
temp[k++]
=
array[begin2++]
;
for
(i
=
0
;
i
<
(r-p)
;
i
++)
array[p+i]
=
temp
;
free(temp)
;
}
//--------------------------------------------------------------------------------
template
void
mergesort(typearray[],
unsigned
int
first,
unsigned
int
last){
int
mid
=
0
;
if
(first
<
last)
{
mid
=
(first+last)/2
;
mergesort
(array,
first,
mid)
;
mergesort
(array,
mid+1,
last)
;
merge
(array,
first,
mid,
last)
;
}
}

❻ 数据结构(c语言)中快速排序什么时候排序最慢,什么情况下使用快速排序

当待排序的序列已经有序(不管是升序还是降序),此时快速排序最慢,一般当数据量很大的时候,用快速排序比较好,为了避免原来的序列有序,一般采用改进的快速排序算法,在排序之前随机交换两个元素的位置,就可以达到目的了,有一本书,叫《算法设计、分析与实现:C、C++和java》徐子珊着。可以看看,里面写了很多基本的算法

❼ 数据结构C语言——实现各种排序算法

刚做完的
#include <iostream>
using namespace std;

void BiInsertsort(int r[], int n) //插入排序(折半)
{
for(int i=2;i<=n;i++)
{
if (r[i]<r[i-1])
{
r[0] = r[i]; //设置哨兵
int low=1,high=i-1; //折半查找
while (low<=high)
{
int mid=(low+high)/2;
if (r[0]<r[mid]) high=mid-1;
else low = mid+1;
}
int j;
for (j=i-1;j>high;j--) r[j+1] = r[j]; //后移
r[j+1] = r[0];
}
}
for(int k=1;k<=n;k++) cout<<r[k]<<" ";
cout<<"\n";
}

void ShellSort ( int r[], int n) //希尔排序
{
for(int d=n/2;d>=1;d=d/2) //以d为增量进行直接插入排序
{
for (int i=d+1;i<=n;i++)
{
r[0] = r[i]; //暂存被插入记录
int j;
for( j=i-d; j>0 && r[0]<r[j]; j=j-d) r[j+d] = r[j]; //记录后移d个位置
r[j+d] = r[0];

}
}
for(int i=1;i<=n;i++) cout<<r[i]<<" ";
cout<<"\n";
}

void BubbleSort(int r[], int n) //起泡排序
{
int temp,exchange,bound;
exchange=n; //第一趟起泡排序的范围是r[0]到r[n-1]
while (exchange) //仅当上一趟排序有记录交换才进行本趟排序
{
bound=exchange;
exchange=0;
for (int j=1; j<bound; j++) //一趟起泡排序
if (r[j]>r[j+1])
{
temp=r[j];
r[j]=r[j+1];
r[j+1]=temp;
exchange=j; //记录每一次发生记录交换的位置
}
}
for(int i=1;i<=n;i++) cout<<r[i]<<" ";
cout<<"\n";
}

int Partition(int r[], int first, int end) //快速排序一次划分
{
int i=first; //初始化
int j=end;
r[0]=r[first];
while (i<j)
{
while (i<j && r[0]<= r[j]) j--; //右侧扫描
r[i]=r[j];
while (i<j && r[i]<= r[0]) i++; //左侧扫描
r[j]=r[i];
}
r[i]=r[0];
return i; //i为轴值记录的最终位置
}
void QuickSort(int r[], int first, int end) //快速排序
{
if (first<end)
{ //递归结束
int pivot=Partition(r, first, end); //一次划分
QuickSort(r, first, pivot-1);//递归地对左侧子序列进行快速排序
QuickSort(r, pivot+1, end); //递归地对右侧子序列进行快速排序
}
}

void SelectSort(int r[ ], int n) //简单选择排序
{
int i,j,index,temp;
for (i=1; i<n; i++) //对n个记录进行n-1趟简单选择排序
{
index=i;
for (j=i+1; j<=n; j++) //在无序区中选取最小记录
if (r[j]<r[index]) index=j;
if (index!=i)
{
temp=r[i];
r[i]=r[index];
r[index]=temp;
}
}
for(i=1;i<=n;i++) cout<<r[i]<<" ";
cout<<"\n";
}

void main()
{
const int numv=12;
int a[3][numv]={{0,6,13,19,23,37,39,41,45,48,58,86},{0,86,58,48,45,41,39,37,23,19,13,6},{0,23,13,48,86,19,6,41,58,37,45,39}};
int z1[numv],z2[numv];
int m,n;
cout<<"请选择测试数据类型:⑴正序 ⑵逆序 ⑶随机 [ 若跳出,请按⑷ ]" <<endl;
cin>>m;
while(m>0&&m<4)
{
cout<<"请选择排序算法:⑴直接插入排序 ⑵希尔排序 ⑶冒泡排序 ⑷快速排序 \n ⑸简单选择排序"<<endl;
cin>>n;
switch(n)
{
case 1:
cout << "直接插入排序前:" << "\n";
for(int j=1;j<numv;j++) cout<<a[m-1][j]<<" ";
cout << "\n直接插入排序结果为:" << "\n";
BiInsertsort(a[m-1],numv-1);
break;
case 2:
cout << "\n希尔排序前:" << "\n";
for(int j=1;j<numv;j++) cout<<a[m-1][j]<<" ";
cout << "\n希尔排序结果为:" << "\n";
ShellSort(a[m-1], numv-1);
break;
case 3:
cout << "\n冒泡排序前:" << "\n";
for(int k=1;k<numv;k++) cout<<a[m-1][k]<<" ";
cout << "\n冒泡排序结果为:" << "\n";
BubbleSort(a[m-1], numv-1);
break;
case 4:
cout << "\n快速排序前:" << "\n";
for(int j=1;j<numv;j++) cout<<a[m-1][j]<<" ";
cout << "\n快速排序结果为:" << "\n";
QuickSort(a[m-1],0,numv-1);
for(int i=1;i<numv;i++)
cout<<a[m-1][i]<<" ";
cout<<"\n";
break;
case 5:
cout << "\n简单选择排序前:" << "\n";
for(int j=1;j<numv;j++) cout<<a[m-1][j]<<" ";
cout << "\n简单选择排序结果为:" << "\n";
SelectSort(a[m-1],numv-1);
break;

default:
cout<<"输入错误!"<<endl;
}
m=0;
cout<<"请选择测试数据类型:⑴正序 ⑵逆序 ⑶随机 [ 若跳出,请按⑷ ]" <<endl;
cin>>m;
}
if(m==4) cout<<"(*^__^*) 再见!"<<endl;
else cout<<"输入错误!"<<endl;
}

❽ c语言三种排序

常用的c语言排序算法主要有三种即冒泡法排序、选择法排序、插入法排序

一、冒泡排序冒泡排序:

是从第一个数开始,依次往后比较,在满足判断条件下进行交换。代码实现(以降序排序为例)

#include<stdio.h>

int main()

{

int array[10] = { 6,9,7,8,5,3,4,0,1,2 };

int temp;

for (int i = 0; i < 10; i++)

{//循环次数

for (int j = 0; j <10 - i-1; j++)

{

if (array[j] < array[j+1])

{//前面一个数比后面的数大时发生交换 temp = array[j];

array[j] = array[j+1];

array[j + 1] = temp;

}

}

} //打印数组 for (int i = 0; i < 10; i++) printf("%2d", array[i]); return 0;}}

二、选择排序以升序排序为例:

就是在指定下标的数组元素往后(指定下标的元素往往是从第一个元素开始,然后依次往后),找出除指定下标元素外的值与指定元素进行对比,满足条件就进行交换。与冒泡排序的区别可以理解为冒泡排序是相邻的两个值对比,而选择排序是遍历数组,找出数组元素与指定的数组元素进行对比。(以升序为例)

#include<stdio.h>

int main()

{

int array[10] = { 6,9,7,8,5,3,4,0,1,2 };

int temp, index;

for (int i = 0; i < 9; i++) {

index = i;

for (int j = i; j < 10; j++)

{

if (array[j] < array[index])

index = j;

}

if(i != index)

{

temp = array[i];

array[i] = array[index];

array[index] = temp;

}

for(int i=0;i<10:i++)

printf("%2d"array[i])

return 0;

}

三、快速排序

是通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

void QuickSort(int* arr, int size)

{

int temp, i, j;

for(i = 1; i <size; i++)

for(j=i; j>0; j--)

{

if(arr[j] <arr[j-1])

{

temp = arr[j];

arr[j]=arr[j-1];

arr[j-1]=temp;

}

}

}

热点内容
安卓哪里填写apple代码 发布:2025-02-05 00:28:54 浏览:290
oppo手机锁屏密码忘记后如何更换 发布:2025-02-05 00:28:19 浏览:26
幼儿思维编程 发布:2025-02-05 00:18:21 浏览:25
我的世界电脑正版如何进入服务器 发布:2025-02-05 00:18:06 浏览:880
疫情防控健康码预警机制演练脚本 发布:2025-02-04 23:58:46 浏览:39
分治算法java 发布:2025-02-04 23:41:15 浏览:593
安卓app点进去就闪退怎么回事 发布:2025-02-04 23:36:56 浏览:780
宏按键编程 发布:2025-02-04 23:05:11 浏览:904
微信隐形密码在哪里设置 发布:2025-02-04 23:05:01 浏览:866
android的补间动画 发布:2025-02-04 23:03:42 浏览:416