當前位置:首頁 » 編程語言 » 希爾排序c語言演算法

希爾排序c語言演算法

發布時間: 2022-12-22 07:14:06

c語言希爾排序

voidShellInsertSort(inta[],intn,intdk)
{
for(inti=dk;i<n;++i){
if(a[i]<a[i-dk]){//若第i個元素大於i-1元素,直接插入。小於的話,移動有序表後插入
intj=i-dk;
intx=a[i];//復制為哨兵,即存儲待排序元素
a[i]=a[i-dk];//首先後移一個元素
while(x<a[j]){//查找在有序表的插入位置
a[j+dk]=a[j];
j-=dk;//元素後移
}
a[j+dk]=x;//插入到正確位置
}
}

}

/**
*先按增量d(n/2,n為要排序數的個數進行希爾排序
*
*/
voidshellSort(inta[],intn){

intdk=n/2;
while(dk>=1){
ShellInsertSort(a,n,dk);
dk=dk/2;
}
}

Ⅱ C語言排序

//總共給你整理了7種排序演算法:希爾排序,鏈式基數排序,歸並排序
//起泡排序,簡單選擇排序,樹形選擇排序,堆排序,先自己看看吧,
//看不懂可以再問身邊的人或者查資料,既然可以上網,我相信你所在的地方信息流通方式應該還行,所有的程序全部在VC++6.0下編譯通過
//希爾排序
#include<stdio.h>
typedef int InfoType; // 定義其它數據項的類型
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#define MAXSIZE 20 // 一個用作示例的小順序表的最大長度
typedef int KeyType; // 定義關鍵字類型為整型
struct RedType // 記錄類型
{
KeyType key; // 關鍵字項
InfoType otherinfo; // 其它數據項,具體類型在主程中定義
};

struct SqList // 順序表類型
{
RedType r[MAXSIZE+1]; // r[0]閑置或用作哨兵單元
int length; // 順序表長度
};
void ShellInsert(SqList &L,int dk)
{ // 對順序表L作一趟希爾插入排序。本演算法是和一趟直接插入排序相比,
// 作了以下修改:
// 1.前後記錄位置的增量是dk,而不是1;
// 2.r[0]只是暫存單元,不是哨兵。當j<=0時,插入位置已找到。演算法10.4
int i,j;
for(i=dk+1;i<=L.length;++i)
if LT(L.r[i].key,L.r[i-dk].key)
{ // 需將L.r[i]插入有序增量子表
L.r[0]=L.r[i]; // 暫存在L.r[0]
for(j=i-dk;j>0&<(L.r[0].key,L.r[j].key);j-=dk)
L.r[j+dk]=L.r[j]; // 記錄後移,查找插入位置
L.r[j+dk]=L.r[0]; // 插入
}
}

void print(SqList L)
{
int i;
for(i=1;i<=L.length;i++)
printf("%d ",L.r[i].key);
printf("\n");
}

void print1(SqList L)
{
int i;
for(i=1;i<=L.length;i++)
printf("(%d,%d)",L.r[i].key,L.r[i].otherinfo);
printf("\n");
}

void ShellSort(SqList &L,int dlta[],int t)
{ // 按增量序列dlta[0..t-1]對順序表L作希爾排序。演算法10.5
int k;
for(k=0;k<t;++k)
{
ShellInsert(L,dlta[k]); // 一趟增量為dlta[k]的插入排序
printf("第%d趟排序結果: ",k+1);
print(L);
}
}

#define N 10
#define T 3
void main()
{
RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8},{55,9},{4,10}};
SqList l;
int dt[T]={5,3,1}; // 增量序列數組
for(int i=0;i<N;i++)
l.r[i+1]=d[i];
l.length=N;
printf("排序前: ");
print(l);
ShellSort(l,dt,T);
printf("排序後: ");
print1(l);
}

/*****************************************************************/
//鏈式基數排序
typedef int InfoType; // 定義其它數據項的類型
typedef int KeyType; // 定義RedType類型的關鍵字為整型
struct RedType // 記錄類型(同c10-1.h)
{
KeyType key; // 關鍵字項
InfoType otherinfo; // 其它數據項
};
typedef char KeysType; // 定義關鍵字類型為字元型
#include<string.h>
#include<ctype.h>
#include<malloc.h> // malloc()等
#include<limits.h> // INT_MAX等
#include<stdio.h> // EOF(=^Z或F6),NULL
#include<stdlib.h> // atoi()
#include<io.h> // eof()
#include<math.h> // floor(),ceil(),abs()
#include<process.h> // exit()
#include<iostream.h> // cout,cin
// 函數結果狀態代碼
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
typedef int Status; // Status是函數的類型,其值是函數結果狀態代碼,如OK等
typedef int Boolean; // Boolean是布爾類型,其值是TRUE或FALSE
#define MAX_NUM_OF_KEY 8 // 關鍵字項數的最大值
#define RADIX 10 // 關鍵字基數,此時是十進制整數的基數
#define MAX_SPACE 1000
struct SLCell // 靜態鏈表的結點類型
{
KeysType keys[MAX_NUM_OF_KEY]; // 關鍵字
InfoType otheritems; // 其它數據項
int next;
};

struct SLList // 靜態鏈表類型
{
SLCell r[MAX_SPACE]; // 靜態鏈表的可利用空間,r[0]為頭結點
int keynum; // 記錄的當前關鍵字個數
int recnum; // 靜態鏈表的當前長度
};

typedef int ArrType[RADIX];
void InitList(SLList &L,RedType D[],int n)
{ // 初始化靜態鏈表L(把數組D中的數據存於L中)
char c[MAX_NUM_OF_KEY],c1[MAX_NUM_OF_KEY];
int i,j,max=D[0].key; // max為關鍵字的最大值
for(i=1;i<n;i++)
if(max<D[i].key)
max=D[i].key;
L.keynum=int(ceil(log10(max)));
L.recnum=n;
for(i=1;i<=n;i++)
{
L.r[i].otheritems=D[i-1].otherinfo;
itoa(D[i-1].key,c,10); // 將10進制整型轉化為字元型,存入c
for(j=strlen(c);j<L.keynum;j++) // 若c的長度<max的位數,在c前補'0'
{
strcpy(c1,"0");
strcat(c1,c);
strcpy(c,c1);
}
for(j=0;j<L.keynum;j++)
L.r[i].keys[j]=c[L.keynum-1-j];
}
}

int ord(char c)
{ // 返回k的映射(個位整數)
return c-'0';
}

void Distribute(SLCell r[],int i,ArrType f,ArrType e) // 演算法10.15
{ // 靜態鍵表L的r域中記錄已按(keys[0],…,keys[i-1])有序。本演算法按
// 第i個關鍵字keys[i]建立RADIX個子表,使同一子表中記錄的keys[i]相同。
// f[0..RADIX-1]和e[0..RADIX-1]分別指向各子表中第一個和最後一個記錄
int j,p;
for(j=0;j<RADIX;++j)
f[j]=0; // 各子表初始化為空表
for(p=r[0].next;p;p=r[p].next)
{
j=ord(r[p].keys[i]); // ord將記錄中第i個關鍵字映射到[0..RADIX-1]
if(!f[j])
f[j]=p;
else
r[e[j]].next=p;
e[j]=p; // 將p所指的結點插入第j個子表中
}
}

int succ(int i)
{ // 求後繼函數
return ++i;
}

void Collect(SLCell r[],ArrType f,ArrType e)
{ // 本演算法按keys[i]自小至大地將f[0..RADIX-1]所指各子表依次鏈接成
// 一個鏈表,e[0..RADIX-1]為各子表的尾指針。演算法10.16
int j,t;
for(j=0;!f[j];j=succ(j)); // 找第一個非空子表,succ為求後繼函數
r[0].next=f[j];
t=e[j]; // r[0].next指向第一個非空子表中第一個結點
while(j<RADIX-1)
{
for(j=succ(j);j<RADIX-1&&!f[j];j=succ(j)); // 找下一個非空子表
if(f[j])
{ // 鏈接兩個非空子表
r[t].next=f[j];
t=e[j];
}
}
r[t].next=0; // t指向最後一個非空子表中的最後一個結點
}

void printl(SLList L)
{ // 按鏈表輸出靜態鏈表
int i=L.r[0].next,j;
while(i)
{
for(j=L.keynum-1;j>=0;j--)
printf("%c",L.r[i].keys[j]);
printf(" ");
i=L.r[i].next;
}
}

void RadixSort(SLList &L)
{ // L是採用靜態鏈表表示的順序表。對L作基數排序,使得L成為按關鍵字
// 自小到大的有序靜態鏈表,L.r[0]為頭結點。演算法10.17
int i;
ArrType f,e;
for(i=0;i<L.recnum;++i)
L.r[i].next=i+1;
L.r[L.recnum].next=0; // 將L改造為靜態鏈表
for(i=0;i<L.keynum;++i)
{ // 按最低位優先依次對各關鍵字進行分配和收集
Distribute(L.r,i,f,e); // 第i趟分配
Collect(L.r,f,e); // 第i趟收集
printf("第%d趟收集後:\n",i+1);
printl(L);
printf("\n");
}
}

void print(SLList L)
{ // 按數組序號輸出靜態鏈表
int i,j;
printf("keynum=%d recnum=%d\n",L.keynum,L.recnum);
for(i=1;i<=L.recnum;i++)
{
printf("keys=");
for(j=L.keynum-1;j>=0;j--)
printf("%c",L.r[i].keys[j]);
printf(" otheritems=%d next=%d\n",L.r[i].otheritems,L.r[i].next);
}
}

void Sort(SLList L,int adr[]) // 改此句(類型)
{ // 求得adr[1..L.length],adr[i]為靜態鏈表L的第i個最小記錄的序號
int i=1,p=L.r[0].next;
while(p)
{
adr[i++]=p;
p=L.r[p].next;
}
}

void Rearrange(SLList &L,int adr[]) // 改此句(類型)
{ // adr給出靜態鏈表L的有序次序,即L.r[adr[i]]是第i小的記錄。
// 本演算法按adr重排L.r,使其有序。演算法10.18(L的類型有變)
int i,j,k;
for(i=1;i<L.recnum;++i) // 改此句(類型)
if(adr[i]!=i)
{
j=i;
L.r[0]=L.r[i]; // 暫存記錄L.r[i]
while(adr[j]!=i)
{ // 調整L.r[adr[j]]的記錄到位直到adr[j]=i為止
k=adr[j];
L.r[j]=L.r[k];
adr[j]=j;
j=k; // 記錄按序到位
}
L.r[j]=L.r[0];
adr[j]=j;
}
}

#define N 10
void main()
{
RedType d[N]={{278,1},{109,2},{63,3},{930,4},{589,5},{184,6},{505,7},{269,8},{8,9},{83,10}};
SLList l;
int *adr;
InitList(l,d,N);
printf("排序前(next域還沒賦值):\n");
print(l);
RadixSort(l);
printf("排序後(靜態鏈表):\n");
print(l);
adr=(int*)malloc((l.recnum)*sizeof(int));
Sort(l,adr);
Rearrange(l,adr);
printf("排序後(重排記錄):\n");
print(l);
}
/*******************************************/
//歸並排序
#include<stdio.h>
typedef int InfoType; // 定義其它數據項的類型
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#define MAXSIZE 20 // 一個用作示例的小順序表的最大長度
typedef int KeyType; // 定義關鍵字類型為整型
struct RedType // 記錄類型
{
KeyType key; // 關鍵字項
InfoType otherinfo; // 其它數據項,具體類型在主程中定義
};

struct SqList // 順序表類型
{
RedType r[MAXSIZE+1]; // r[0]閑置或用作哨兵單元
int length; // 順序表長度
};
void Merge(RedType SR[],RedType TR[],int i,int m,int n)
{ // 將有序的SR[i..m]和SR[m+1..n]歸並為有序的TR[i..n] 演算法10.12
int j,k,l;
for(j=m+1,k=i;i<=m&&j<=n;++k) // 將SR中記錄由小到大地並入TR
if LQ(SR[i].key,SR[j].key)
TR[k]=SR[i++];
else
TR[k]=SR[j++];
if(i<=m)
for(l=0;l<=m-i;l++)
TR[k+l]=SR[i+l]; // 將剩餘的SR[i..m]復制到TR
if(j<=n)
for(l=0;l<=n-j;l++)
TR[k+l]=SR[j+l]; // 將剩餘的SR[j..n]復制到TR
}

void MSort(RedType SR[],RedType TR1[],int s, int t)
{ // 將SR[s..t]歸並排序為TR1[s..t]。演算法10.13
int m;
RedType TR2[MAXSIZE+1];
if(s==t)
TR1[s]=SR[s];
else
{
m=(s+t)/2; // 將SR[s..t]平分為SR[s..m]和SR[m+1..t]
MSort(SR,TR2,s,m); // 遞歸地將SR[s..m]歸並為有序的TR2[s..m]
MSort(SR,TR2,m+1,t); // 遞歸地將SR[m+1..t]歸並為有序的TR2[m+1..t]
Merge(TR2,TR1,s,m,t); // 將TR2[s..m]和TR2[m+1..t]歸並到TR1[s..t]
}
}

void MergeSort(SqList &L)
{ // 對順序表L作歸並排序。演算法10.14
MSort(L.r,L.r,1,L.length);
}

void print(SqList L)
{
int i;
for(i=1;i<=L.length;i++)
printf("(%d,%d)",L.r[i].key,L.r[i].otherinfo);
printf("\n");
}

#define N 7
void main()
{
RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7}};
SqList l;
int i;
for(i=0;i<N;i++)
l.r[i+1]=d[i];
l.length=N;
printf("排序前:\n");
print(l);
MergeSort(l);
printf("排序後:\n");
print(l);
}
/**********************************************/
//起泡排序
#include<string.h>
#include<ctype.h>
#include<malloc.h> // malloc()等
#include<limits.h> // INT_MAX等
#include<stdio.h> // EOF(=^Z或F6),NULL
#include<stdlib.h> // atoi()
#include<io.h> // eof()
#include<math.h> // floor(),ceil(),abs()
#include<process.h> // exit()
#include<iostream.h> // cout,cin
// 函數結果狀態代碼
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
typedef int Status;
typedef int Boolean;
#define N 8
void bubble_sort(int a[],int n)
{ // 將a中整數序列重新排列成自小至大有序的整數序列(起泡排序)
int i,j,t;
Status change;
for(i=n-1,change=TRUE;i>1&&change;--i)
{
change=FALSE;
for(j=0;j<i;++j)
if(a[j]>a[j+1])
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
change=TRUE;
}
}
}

void print(int r[],int n)
{
int i;
for(i=0;i<n;i++)
printf("%d ",r[i]);
printf("\n");
}

void main()
{
int d[N]={49,38,65,97,76,13,27,49};
printf("排序前:\n");
print(d,N);
bubble_sort(d,N);
printf("排序後:\n");
print(d,N);
}
/****************************************************/
//簡單選擇排序
#include<stdio.h>
typedef int InfoType; // 定義其它數據項的類型
#define MAXSIZE 20 // 一個用作示例的小順序表的最大長度
typedef int KeyType; // 定義關鍵字類型為整型
struct RedType // 記錄類型
{
KeyType key; // 關鍵字項
InfoType otherinfo; // 其它數據項,具體類型在主程中定義
};

struct SqList // 順序表類型
{
RedType r[MAXSIZE+1]; // r[0]閑置或用作哨兵單元
int length; // 順序表長度
};
int SelectMinKey(SqList L,int i)
{ // 返回在L.r[i..L.length]中key最小的記錄的序號
KeyType min;
int j,k;
k=i; // 設第i個為最小
min=L.r[i].key;
for(j=i+1;j<=L.length;j++)
if(L.r[j].key<min) // 找到更小的
{
k=j;
min=L.r[j].key;
}
return k;
}

void SelectSort(SqList &L)
{ // 對順序表L作簡單選擇排序。演算法10.9
int i,j;
RedType t;
for(i=1;i<L.length;++i)
{ // 選擇第i小的記錄,並交換到位
j=SelectMinKey(L,i); // 在L.r[i..L.length]中選擇key最小的記錄
if(i!=j)
{ // 與第i個記錄交換
t=L.r[i];
L.r[i]=L.r[j];
L.r[j]=t;
}
}
}

void print(SqList L)
{
int i;
for(i=1;i<=L.length;i++)
printf("(%d,%d)",L.r[i].key,L.r[i].otherinfo);
printf("\n");
}

#define N 8
void main()
{
RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}};
SqList l;
int i;
for(i=0;i<N;i++)
l.r[i+1]=d[i];
l.length=N;
printf("排序前:\n");
print(l);
SelectSort(l);
printf("排序後:\n");
print(l);
}
/************************************************/
//樹形選擇排序
#include<string.h>
#include<ctype.h>
#include<malloc.h> // malloc()等
#include<limits.h> // INT_MAX等
#include<stdio.h> // EOF(=^Z或F6),NULL
#include<stdlib.h> // atoi()
#include<io.h> // eof()
#include<math.h> // floor(),ceil(),abs()
#include<process.h> // exit()
#include<iostream.h> // cout,cin
// 函數結果狀態代碼
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
typedef int Status; // Status是函數的類型,其值是函數結果狀態代碼,如OK等
typedef int Boolean; // Boolean是布爾類型,其值是TRUE或FALSE
typedef int InfoType; // 定義其它數據項的類型
#define MAXSIZE 20 // 一個用作示例的小順序表的最大長度
typedef int KeyType; // 定義關鍵字類型為整型
struct RedType // 記錄類型
{
KeyType key; // 關鍵字項
InfoType otherinfo; // 其它數據項,具體類型在主程中定義
};

struct SqList // 順序表類型
{
RedType r[MAXSIZE+1]; // r[0]閑置或用作哨兵單元
int length; // 順序表長度
};
void TreeSort(SqList &L)
{ // 樹形選擇排序
int i,j,j1,k,k1,l,n=L.length;
RedType *t;
l=(int)ceil(log(n)/log(2))+1; // 完全二叉樹的層數
k=(int)pow(2,l)-1; // l層完全二叉樹的結點總數
k1=(int)pow(2,l-1)-1; // l-1層完全二叉樹的結點總數
t=(RedType*)malloc(k*sizeof(RedType)); // 二叉樹採用順序存儲結構
for(i=1;i<=n;i++) // 將L.r賦給葉子結點
t[k1+i-1]=L.r[i];
for(i=k1+n;i<k;i++) // 給多餘的葉子的關鍵字賦無窮大
t[i].key=INT_MAX;
j1=k1;
j=k;
while(j1)
{ // 給非葉子結點賦值
for(i=j1;i<j;i+=2)
t[i].key<t[i+1].key?(t[(i+1)/2-1]=t[i]):(t[(i+1)/2-1]=t[i+1]);
j=j1;
j1=(j1-1)/2;
}
for(i=0;i<n;i++)
{
L.r[i+1]=t[0]; // 將當前最小值賦給L.r[i]
j1=0;
for(j=1;j<l;j++) // 沿樹根找結點t[0]在葉子中的序號j1
t[2*j1+1].key==t[j1].key?(j1=2*j1+1):(j1=2*j1+2);
t[j1].key=INT_MAX;
while(j1)
{
j1=(j1+1)/2-1; // 序號為j1的結點的雙親結點序號
t[2*j1+1].key<=t[2*j1+2].key?(t[j1]=t[2*j1+1]):(t[j1]=t[2*j1+2]);
}
}
free(t);
}

void print(SqList L)
{
int i;
for(i=1;i<=L.length;i++)
printf("(%d,%d)",L.r[i].key,L.r[i].otherinfo);
printf("\n");
}

#define N 8
void main()
{
RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}};
SqList l;
int i;
for(i=0;i<N;i++)
l.r[i+1]=d[i];
l.length=N;
printf("排序前:\n");
print(l);
TreeSort(l);
printf("排序後:\n");
print(l);
}
/****************************/
//堆排序
#include<stdio.h>
typedef int InfoType; // 定義其它數據項的類型
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#define MAXSIZE 20 // 一個用作示例的小順序表的最大長度
typedef int KeyType; // 定義關鍵字類型為整型
struct RedType // 記錄類型
{
KeyType key; // 關鍵字項
InfoType otherinfo; // 其它數據項,具體類型在主程中定義
};

struct SqList // 順序表類型
{
RedType r[MAXSIZE+1]; // r[0]閑置或用作哨兵單元
int length; // 順序表長度
};

typedef SqList HeapType; // 堆採用順序表存儲表示
void HeapAdjust(HeapType &H,int s,int m) // 演算法10.10
{ // 已知H.r[s..m]中記錄的關鍵字除H.r[s].key之外均滿足堆的定義,本函數
// 調整H.r[s]的關鍵字,使H.r[s..m]成為一個大頂堆(對其中記錄的關鍵字而言)
RedType rc;
int j;
rc=H.r[s];
for(j=2*s;j<=m;j*=2)
{ // 沿key較大的孩子結點向下篩選
if(j<m&<(H.r[j].key,H.r[j+1].key))
++j; // j為key較大的記錄的下標
if(!LT(rc.key,H.r[j].key))
break; // rc應插入在位置s上
H.r[s]=H.r[j];
s=j;
}
H.r[s]=rc; // 插入
}

void HeapSort(HeapType &H)
{ // 對順序表H進行堆排序。演算法10.11
RedType t;
int i;
for(i=H.length/2;i>0;--i) // 把H.r[1..H.length]建成大頂堆
HeapAdjust(H,i,H.length);
for(i=H.length;i>1;--i)
{ // 將堆頂記錄和當前未經排序子序列H.r[1..i]中最後一個記錄相互交換
t=H.r[1];
H.r[1]=H.r[i];
H.r[i]=t;
HeapAdjust(H,1,i-1); // 將H.r[1..i-1]重新調整為大頂堆
}
}

void print(HeapType H)
{
int i;
for(i=1;i<=H.length;i++)
printf("(%d,%d)",H.r[i].key,H.r[i].otherinfo);
printf("\n");
}

#define N 8
void main()
{
RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}};
HeapType h;
int i;
for(i=0;i<N;i++)
h.r[i+1]=d[i];
h.length=N;
printf("排序前:\n");
print(h);
HeapSort(h);
printf("排序後:\n");
print(h);
}

Ⅲ 希爾排序怎麼排啊

下標0123456789
數組4938659726132750554(原數組)

增量=5,[0]=49與[5]=13為一組,互換為1349(排序是從小到大)
[1]=38與[6]=27為一組,互換為2738
[2]=65與[7]=50為一組,互換為5065
[3]=97與[8]=55為一組,互換為5597
[4]=26與[9]=4為一組,互換為426

增量=5的排序結果是:1327505544938659726


下標0123456789
數組1327505544938659726(第一趟之後)

增量=2,[0]=13,[2]=50,[4]=4,[6]=38,[8]=97為一組,
互換之後,[0]=4,[2]=13,[4]=38,[6]=50,[8]=97

[1]=27,[3]=55,[5]=49,[7]=65,[9]=26為一組,
互換之後,[1]=26,[3]=27,[5]=49,[7]=55,[9]=65

增量=2的排序結果是:4261327384950559765


下標0123456789
數組4261327384950559765(第二趟之後)

增量=1,數組里的10個數據作為一組,其中,
[1]=26有[2]=13互換為1326
[8]=97與[9]=65互換為6597

增量=1的排序結果是:4132627384950556597


//C語言測試代碼
//希爾排序法(自定增量)
#include<stdio.h>
#include<stdlib.h>

voidprintData(intdata[],intn)//列印數組
{
inti;
for(i=0;i<n;i++)
{
printf("%d",data[i]);
}
printf(" ");
}

//希爾排序(從小到大)
voidshell(intdata[],intcount)
{
intoffset_a[3]={5,2,1};//每一趟的增量
intlen;
intpos;
intoffset;
inti,j;
inttemp;
len=sizeof(offset_a)/sizeof(int);
for(i=0;i<len;i++)
{
offset=offset_a[i];
for(j=offset;j<count;j++)
{
temp=data[j];
pos=j-offset;
while(temp<data[pos]&&pos>=0&&j<=count)
{
data[pos+offset]=data[pos];
pos=pos-offset;
}
data[pos+offset]=temp;
}
printf("增量=%d,排序結果:",offset);
printData(data,count);
}
}

intmain(void)
{
intdata[]={49,38,65,97,26,13,27,50,55,4};
intcount;
count=sizeof(data)/sizeof(int);
printf("原數組:");
printData(data,count);

shell(data,count);

printf(" 最後的排序結果:");
printData(data,count);
return0;
}

Ⅳ 怎樣用C語言對一串整行數從大到小排序

方法太多了,當然各種時間排序的時間復雜度和空間復雜度不同、穩定性也不同。最簡單的我覺得就是冒泡排序了,也最形像。/*
================================================
功能:選擇排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================
*/
/*
====================================================
演算法思想簡單描述: 在要排序的一組數中,選出最小的一個數與第一個位置的數交換;
然後在剩下的數當中再找最小的與第二個位置的數交換,如此循環
到倒數第二個數和最後一個數比較為止。 選擇排序是不穩定的。演算法復雜度O(n2)--[n的平方]
=====================================================
*/
void select_sort(int *x, int n)
{
int i, j, min, t; for (i=0; i<n-1; i++) /*要選擇的次數:0~n-2共n-1次*/
{
min = i; /*假設當前下標為i的數最小,比較後再調整*/
for (j=i+1; j<n; j++)/*循環找出最小的數的下標是哪個*/
{
if (*(x+j) < *(x+min))
{
min = j; /*如果後面的數比前面的小,則記下它的下標*/
}
}

if (min != i) /*如果min在循環中改變了,就需要交換數據*/
{
t = *(x+i);
*(x+i) = *(x+min);
*(x+min) = t;
}
}
}
/*
================================================
功能:直接插入排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================
*/
/*
====================================================
演算法思想簡單描述: 在要排序的一組數中,假設前面(n-1) [n>=2] 個數已經是排
好順序的,現在要把第n個數插到前面的有序數中,使得這n個數
也是排好順序的。如此反復循環,直到全部排好順序。

直接插入排序是穩定的。演算法時間復雜度O(n2)--[n的平方]
=====================================================
*/
void insert_sort(int *x, int n)
{
int i, j, t; for (i=1; i<n; i++) /*要選擇的次數:1~n-1共n-1次*/
{
/*
暫存下標為i的數。注意:下標從1開始,原因就是開始時
第一個數即下標為0的數,前面沒有任何數,單單一個,認為
它是排好順序的。
*/
t=*(x+i);
for (j=i-1; j>=0 && t<*(x+j); j--) /*注意:j=i-1,j--,這里就是下標為i的數,在它前面有序列中找插入位置。*/
{
*(x+j+1) = *(x+j); /*如果滿足條件就往後挪。最壞的情況就是t比下標為0的數都小,它要放在最前面,j==-1,退出循環*/
} *(x+j+1) = t; /*找到下標為i的數的放置位置*/
}
}
/*
================================================
功能:冒泡排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================
*/
/*
====================================================
演算法思想簡單描述: 在要排序的一組數中,對當前還未排好序的范圍內的全部數,自上
而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較
小的往上冒。即:每當兩相鄰的數比較後發現它們的排序與排序要
求相反時,就將它們互換。

下面是一種改進的冒泡演算法,它記錄了每一遍掃描後最後下沉數的
位置k,這樣可以減少外層循環掃描的次數。 冒泡排序是穩定的。演算法時間復雜度O(n2)--[n的平方]
=====================================================
*/void bubble_sort(int *x, int n)
{
int j, k, h, t;

for (h=n-1; h>0; h=k) /*循環到沒有比較范圍*/
{
for (j=0, k=0; j<h; j++) /*每次預置k=0,循環掃描後更新k*/
{
if (*(x+j) > *(x+j+1)) /*大的放在後面,小的放到前面*/
{
t = *(x+j);
*(x+j) = *(x+j+1);
*(x+j+1) = t; /*完成交換*/
k = j; /*保存最後下沉的位置。這樣k後面的都是排序排好了的。*/
}
}
}
}
/*
================================================
功能:希爾排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================
*/
/*
====================================================
演算法思想簡單描述:

在直接插入排序演算法中,每次插入一個數,使有序序列只增加1個節點,
並且對插入下一個數沒有提供任何幫助。如果比較相隔較遠距離(稱為
增量)的數,使得數移動時能跨過多個元素,則進行一次比較就可能消除
多個元素交換。D.L.shell於1959年在以他名字命名的排序演算法中實現
了這一思想。演算法先將要排序的一組數按某個增量d分成若干組,每組中
記錄的下標相差d.對每組中全部元素進行排序,然後再用一個較小的增量
對它進行,在每組中再進行排序。當增量減到1時,整個要排序的數被分成
一組,排序完成。

下面的函數是一個希爾排序演算法的一個實現,初次取序列的一半為增量,
以後每次減半,直到增量為1。 希爾排序是不穩定的。
=====================================================
*/
void shell_sort(int *x, int n)
{
int h, j, k, t; for (h=n/2; h>0; h=h/2) /*控制增量*/
{
for (j=h; j<n; j++) /*這個實際上就是上面的直接插入排序*/
{
t = *(x+j);
for (k=j-h; (k>=0 && t<*(x+k)); k-=h)
{
*(x+k+h) = *(x+k);
}
*(x+k+h) = t;
}
}
}/*
================================================
功能:快速排序
輸入:數組名稱(也就是數組首地址)、數組中起止元素的下標
================================================
*/
/*
====================================================
演算法思想簡單描述: 快速排序是對冒泡排序的一種本質改進。它的基本思想是通過一趟
掃描後,使得排序序列的長度能大幅度地減少。在冒泡排序中,一次
掃描只能確保最大數值的數移到正確位置,而待排序序列的長度可能只
減少1。快速排序通過一趟掃描,就能確保某個數(以它為基準點吧)
的左邊各數都比它小,右邊各數都比它大。然後又用同樣的方法處理
它左右兩邊的數,直到基準點的左右只有一個元素為止。它是由
C.A.R.Hoare於1962年提出的。

顯然快速排序可以用遞歸實現,當然也可以用棧化解遞歸實現。下面的
函數是用遞歸實現的,有興趣的朋友可以改成非遞歸的。 快速排序是不穩定的。最理想情況演算法時間復雜度O(nlog2n),最壞O(n2)

=====================================================
*/
void quick_sort(int *x, int low, int high)
{
int i, j, t; if (low < high) /*要排序的元素起止下標,保證小的放在左邊,大的放在右邊。這里以下標為low的元素為基準點*/
{
i = low;
j = high;
t = *(x+low); /*暫存基準點的數*/ while (i<j) /*循環掃描*/
{
while (i<j && *(x+j)>t) /*在右邊的只要比基準點大仍放在右邊*/
{
j--; /*前移一個位置*/
} if (i<j)
{
*(x+i) = *(x+j); /*上面的循環退出:即出現比基準點小的數,替換基準點的數*/
i++; /*後移一個位置,並以此為基準點*/
} while (i<j && *(x+i)<=t) /*在左邊的只要小於等於基準點仍放在左邊*/
{
i++; /*後移一個位置*/
} if (i<j)
{
*(x+j) = *(x+i); /*上面的循環退出:即出現比基準點大的數,放到右邊*/
j--; /*前移一個位置*/
}
} *(x+i) = t; /*一遍掃描完後,放到適當位置*/
quick_sort(x,low,i-1); /*對基準點左邊的數再執行快速排序*/
quick_sort(x,i+1,high); /*對基準點右邊的數再執行快速排序*/
}
}
/*
================================================
功能:堆排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================
*/
/*
====================================================
演算法思想簡單描述: 堆排序是一種樹形選擇排序,是對直接選擇排序的有效改進。
堆的定義如下:具有n個元素的序列(h1,h2,...,hn),當且僅當
滿足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1)(i=1,2,...,n/2)
時稱之為堆。在這里只討論滿足前者條件的堆。 由堆的定義可以看出,堆頂元素(即第一個元素)必為最大項。完全二叉樹可以
很直觀地表示堆的結構。堆頂為根,其它為左子樹、右子樹。
初始時把要排序的數的序列看作是一棵順序存儲的二叉樹,調整它們的存儲順序,
使之成為一個堆,這時堆的根節點的數最大。然後將根節點與堆的最後一個節點
交換。然後對前面(n-1)個數重新調整使之成為堆。依此類推,直到只有兩個節點
的堆,並對它們作交換,最後得到有n個節點的有序序列。 從演算法描述來看,堆排序需要兩個過程,一是建立堆,二是堆頂與堆的最後一個元素
交換位置。所以堆排序有兩個函數組成。一是建堆的滲透函數,二是反復調用滲透函數
實現排序的函數。 堆排序是不穩定的。演算法時間復雜度O(nlog2n)。*/
/*
功能:滲透建堆
輸入:數組名稱(也就是數組首地址)、參與建堆元素的個數、從第幾個元素開始
*/
void sift(int *x, int n, int s)
{
int t, k, j; t = *(x+s); /*暫存開始元素*/
k = s; /*開始元素下標*/
j = 2*k + 1; /*右子樹元素下標*/ while (j<n)
{
if (j<n-1 && *(x+j) < *(x+j+1))/*判斷是否滿足堆的條件:滿足就繼續下一輪比較,否則調整。*/
{
j++;
} if (t<*(x+j)) /*調整*/
{
*(x+k) = *(x+j);
k = j; /*調整後,開始元素也隨之調整*/
j = 2*k + 1;
}
else /*沒有需要調整了,已經是個堆了,退出循環。*/
{
break;
}
}

*(x+k) = t; /*開始元素放到它正確位置*/
}
/*
功能:堆排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
*/
void heap_sort(int *x, int n)
{
int i, k, t;
int *p; for (i=n/2-1; i>=0; i--)
{
sift(x,n,i); /*初始建堆*/
}

for (k=n-1; k>=1; k--)
{
t = *(x+0); /*堆頂放到最後*/
*(x+0) = *(x+k);
*(x+k) = t;
sift(x,k,0); /*剩下的數再建堆*/
}
}
void main()
{
#define MAX 4
int *p, i, a[MAX];

/*錄入測試數據*/
p = a;
printf("Input %d number for sorting :\n",MAX);
for (i=0; i<MAX; i++)
{
scanf("%d",p++);
}
printf("\n"); /*測試選擇排序*/
p = a;
select_sort(p,MAX);
/**/
/*測試直接插入排序*/ /*
p = a;
insert_sort(p,MAX);
*/
/*測試冒泡排序*/ /*
p = a;
insert_sort(p,MAX);
*/ /*測試快速排序*/ /*
p = a;
quick_sort(p,0,MAX-1);
*/ /*測試堆排序*/ /*
p = a;
heap_sort(p,MAX);
*/ for (p=a, i=0; i<MAX; i++)
{
printf("%d ",*p++);
}

printf("\n");
system("pause");
}

Ⅳ C語言 各常見排序法的時間復雜度 急 請簡單說明

選擇排序演算法復雜度是O(n^2)。
插入排序是O(n^2)
快速排序快速排序是不穩定的。最理想情況演算法時間復雜度O(nlog2n),最壞O(n^2)。
堆排序演算法時間復雜度O(nlogn)。
歸並排序的時間復雜度是O(nlog2n)。

Ⅵ 什麼是希爾排序法

基本思想:
將整個無序序列分割成若干小的子序列分別進行插入排序。

序列分割方法:將相隔某個增量h的元素構成一個子序列。在排序過程中,逐次減小這個增量,最後當h減到1時,進行一次插入排序,排序就完成。增量序列一般採用:ht=2t-1,1≤t≤[log2n],其中n為待排序序列的長度。
void prshl(p,n)

int n;double p[];

{

int k,j,i;

double t;

k=n/2;

while(k>0)

{

for(j=k;j<=n-1;j++)

{

t=p[j];i=j-k;

while((i>=0)&&(p[i]>t))

{

p[i+k]=p[i];i=i-k;

}

p[i+k]=t;

}

k=k/2;

}

return;

}
希爾排序(縮小增量法)
屬於插入類排序,是將整個無序列分割成若干小的子序列分別進行插入排序
排序過程:先取一個正整數d1<n,把所有序號相隔d1的數組元素放一組,組內進行直接插入排序;然後取d2<d1,重復上述分組和排序操作;直至di=1,即所有記錄放進一個組中排序為止

初始:d=5
49 38 65 97 76 13 27 49* 55 04
|---------------|
38 27
|--------------|
65 49*
|--------------|
97 55
|---------------|
|76-------------04|
一趟結果

d=3 13 27 49*55 04 49 38 65 97 76
|--------|--------|----------|
27 04 65
|--------|-------|
49* 49 97
|--------|---------|
二趟結果
13 04 49*38 27 49 66 65 97 76
d=1
三趟結果
04 13 27 38 49*49 55 65 76 97

Ⅶ C語言數據結構希爾排序

void main()
{
datatype R[MAXNUM];
int d[6]=[50,25,12,6,3,2,1];

for(int i=0;i<MAXNUM;i++)
scanf("%d",&R[i].key);
ShellSort(R,MAXNUM,d,6);
for(int i=0;i<MAXNUM;i++)
printf("%d",R[i].key);
}

Ⅷ C語言排序演算法一共多少種

  1. 選擇排序

#include<iostream>
usingnamespacestd;
voidselect_sort(intarr[],intnum);
voidoutput_array(intarr[],intnum);
intmain()
{
inta[10];
for(inti=0;i<10;i++)
{
cin>>a[i];
}
select_sort(a,10);
output_array(a,10);
return0;
}
voidselect_sort(intarray[],intn)//形參array是數組名
{
inti,j,k,t;
for(i=0;i<n-1;i++)
{
k=i;//先設第i個就為最小
for(j=i+1;j<n;j++)
if(array[j]<array[k])
k=j;//通過循環,得到k為最小
t=array[k];//交換a[i]和a[k]
array[k]=array[i];
array[i]=t;
}
return;
}
voidoutput_array(intarr[],intnum)
{
inti;
for(i=0;i<num;i++)
{
cout<<arr[i];
cout<<endl;
}
return;
}

2.冒泡排序

#include<stdio.h>
intmain()
{
inti,j,a[10],t;
for(i=0;i<10;i++)
scanf("%d",&a[i]);
for(i=0;i<10;i++)
for(j=i+1;j<10;j++)
if(a[i]>a[j])
{
t=a[j];
a[j]=a[i];
a[i]=t;
}
for(i=0;i<10;i++)
printf("%d",a[i]);
return0;
}

3.堆排序

#include<iostream>
usingnamespacestd;
voidpaii(inta[20],inti,intm)
{
intk,t;
t=a[i];
k=2*i+1;
while(k<m)
{
if((k<m-1)&&(a[k]<a[k+1]))
k++;
if(t<a[k])
{
a[i]=a[k];
i=k;
k=2*i+1;
}
elsebreak;
}
a[i]=t;
}
voidipai(inta[20],intn)
{
inti,k;
for(i=n/2-1;i>=0;i--)
paii(a,i,n);
for(i=n-1;i>=1;i--)
{
k=a[0];
a[0]=a[i];
a[i]=k;
paii(a,0,i);
}}
intmain()
{
inta[10],i;
for(i=0;i<10;i++)
cin>>a[i];
ipai(a,10);
for(i=0;i<10;i++)
cout<<a[i]<<endl;
}

4.快速排序

#include<iostream>
usingnamespacestd;
voidQuicksort(inta[],intlow,inthigh)
{
if(low>=high)
{
return;
}
intfirst=low;
intlast=high;
intkey=a[first];
while(first<last)
{
while(first<last&&a[last]>=key)
--last;
a[first]=a[last];
while(first<last&&a[first]<=key)
++first;
a[last]=a[first];
}
a[first]=key;
Quicksort(a,low,first-1);
Quicksort(a,last+1,high);
}


intmain()
{
inti,a[100],x,n=0;
while(cin>>x)
{
a[n]=x;
n++;
}
n--;
Quicksort(a,0,n);
for(i=0;i<=n;i++)
cout<<a[i]<<"";
cout<<endl;
return0;
}

5. 基數排序

#include<stdio.h>
#include<stdlib.h>
intmain(){
intdata[10]={73,22,93,43,55,14,82,65,39,81};//對十個數進行排序
inttemp[10][10]={0};//構造一個臨時二維數組,其值為0
intorder[10]={0};//構造一維數組,其值為0
inti,j,k,n,lsd;
k=0;n=1;
for(i=0;i<10;i++)printf("%d",data[i]);//在排序前,對這10個數列印一遍
putchar(' ');
while(n<=10){
for(i=0;i<10;i++){
lsd=((data[i]/n)%10);//lsd先對個位取余,然後再對十位取余,注意循環
temp[lsd][order[lsd]]=data[i];//temp[3][0]=73,temp[2][0]=22,temp[3][1]=93,temp[3][2]=43,⋯⋯
order[lsd]++;//需要區分的是lsd和order[lsd],這兩個不是一樣的概念嗷
}
printf(" 重新排列:");
for(i=0;i<10;i++){
if(order[i]!=0)
for(j=0;j<order[i];j++){


data[k]=temp[i][j];
printf("%d",data[k]);
k++;
}
order[i]=0;
}
n*=10;//第二次用十位
k=0;
}
putchar(' ');
printf(" 排序後:");
for(i=0;i<10;i++)printf("%d",data[i]);
return0;
}

6.希爾排序

#include<iostream>
usingnamespacestd;
voidshell_sort(inta[],intn);
intmain()
{
intn,a[10000];
cin>>n;
for(inty=0;y<n;y++)
cin>>a[y];
shell_sort(a,n);
for(inti=0;i<n;i++)
cout<<a[i]<<"";
cout<<endl;
}

voidshell_sort(inta[],intn)
{
intgap,k,temp;//定義增量;
for(gap=3;gap>0;gap--)//設置初始增量,遞減;
{
for(inti=0;i<gap;i++)//按增量分組;
{
for(intj=i+gap;j<n;j=j+gap)//每組分別比較大小;
{
if(a[j]<a[j-gap])
{
temp=a[j];
k=j-gap;
while(k>=0&&a[k]>temp)
{
a[k+gap]=a[k];
k=k-gap;
}

a[k+gap]=temp;
}
}
}
}
}

7.歸並排序

#include<iostream>
usingnamespacestd;
voidMergeSort(intp[],ints,intm,intt)
{
intq[100];//q[100]用來存放排好的序列
inti=s;
intj=m+1;
intk=s;
while(i<=m&&j<=t)
{
if(p[i]<=p[j])
q[k++]=p[i++];
else
q[k++]=p[j++];
}
if(i<=m)
while(i<=m)
q[k++]=p[i++];
elsewhile(j<=t)
q[k++]=p[j++];
for(intn=s;n<=t;n++)
p[n]=q[n];
}
voidMerge(intp[],ints,intt)
{
if(s<t)
{
intm=(s+t)/2;//將數組分成兩半
Merge(p,s,m);//遞歸拆分左數組
Merge(p,m+1,t);//遞歸拆分右數組
MergeSort(p,s,m,t);//合並數組
}
}
intmain()
{
intn;
intp[100];
cin>>n;
for(inti=0;i<n;i++)
cin>>p[i];
Merge(p,0,n-1);
for(intj=0;j<n;j++)
cout<<p[j]<<"";
cout<<endl;
return0;
}

排序方法基本就這些,還有雙向冒泡這種拓展的排序方法,還有直接排序如桶排序

熱點內容
不用internet打開ftp 發布:2025-05-15 23:06:00 瀏覽:152
sql字元串取數字 發布:2025-05-15 22:57:45 瀏覽:123
推薦編程課 發布:2025-05-15 22:34:12 瀏覽:617
表拒絕訪問 發布:2025-05-15 22:29:37 瀏覽:978
電腦怎樣解壓文件 發布:2025-05-15 22:25:32 瀏覽:439
dns伺服器怎麼看 發布:2025-05-15 22:17:27 瀏覽:151
3dm的壓縮包 發布:2025-05-15 22:09:23 瀏覽:662
和存儲字長 發布:2025-05-15 21:54:09 瀏覽:515
用什麼寫c語言 發布:2025-05-15 21:35:56 瀏覽:418
linux讀取u盤 發布:2025-05-15 21:32:13 瀏覽:508