當前位置:首頁 » 編程語言 » c語言非數值的排序
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

c語言非數值的排序

發布時間: 2022-08-16 06:28:14

『壹』 c語言如何將一個無序的數組從小到大排列

#include <stdio.h>
#include <stdlib.h>
#define N 5
int main()
{

int i, j; //循環變數
int temp; //用來交換的臨時變數
int nums[N] = {16, 25, 9, 90, 23};
//外層循環控制輪數
for(i = 0; i < N - 1; i++)
{
//內層循環控制每輪的比較次數
for(j = 0; j < N - i - 1; j++)
{
//如果當前值大於後一個值,就交換
if(nums[j] > nums[j + 1])
{
temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
}
printf("排序後的結果是:\n");
for(i = 0; i < N; i++)
{
printf("%d\t",nums[i]);
}
return 0;
}

『貳』 c語言中,什麼叫做非數值運算演算法能不能具體舉例說明一下,哪一類的演算法叫做非數值運算演算法

字元串的查找、排序等,都不是樹枝運算演算法

『叄』 C語言10種排序方法

1.比較法2.選擇排序3.冒泡排序4.希爾排序5.快速排序6.堆排序7.合並排序8.基數排序9.折半插入排序10.直接插入排序

『肆』 用C語言實現從鍵盤上輸入不確定個數的數字,將數字從小到大排序後輸出

對於輸入的數據的個數不確定的情況,一般會預設一個特殊的非法值(這個值是屬於論域之外的一個值)作為終止值,例如如果論域是正整數,則通常會將0作為終止值,即當輸入0時結束,且0不作為有效數據。

因此如果你要輸入的都是正整數,則程序可如下(對於其它情況可採用類似方法)

#include <stdio.h>

void Sort(int *s, int left, int right)
{
int i, j, min, tmp;
for(i = left; i < right; i++)
{
for(min = i, j = i + 1; j <= right; j++)
if(s[j] < s[min]) min = j;
if(min != i) tmp = s[i], s[i] = s[min], s[min] = tmp;
}
}

void main( )
{
int i, s[1000], length = 0, data;
scanf("%d", &data);
while(data > 0)
{
s[length++] = data;
scanf("%d", &data);
}
Sort(s, 0, length - 1);
for(i = 0; i < length; i++)
printf("%-4d", s[i]);
}

運行結果:

『伍』 c語言的兩種排序

1、選擇排序法

要求輸入10個整數,從大到小排序輸出

輸入:2 0 3 -4 8 9 5 1 7 6

輸出:9 8 7 6 5 3 2 1 0 -4

代碼:

#include&lt;stdio.h&gt;

int main(int argc,const char*argv[]){

int num[10],i,j,k,l,temp;

//用一個數組保存輸入的數據

for(i=0;i&lt;=9;i++)

{

scanf("%d",&num&lt;i&gt;);

}

//用兩個for嵌套循環來進行數據大小比較進行排序

for(j=0;j&lt;9;j++)

{

for(k=j+1;k&lt;=9;k++)

{

if(num[j]&lt;num[k])//num[j]&lt;num[k]

{

temp=num[j];

num[j]=num[k];

num[k]=temp;

}

}

}

//用一個for循環來輸出數組中排序好的數據

for(l=0;l&lt;=9;l++)

{

printf("%d",num[l]);

}

return 0;

}

2、冒泡排序法

要求輸入10個整數,從大到小排序輸出

輸入:2 0 3-4 8 9 5 1 7 6

輸出:9 8 7 6 5 3 2 1 0-4

代碼:

#include&lt;stdio.h&gt;

int main(int argc,const char*argv[]){

//用一個數組來存數據

int num[10],i,j,k,l,temp;

//用for來把數據一個一個讀取進來

for(i=0;i&lt;=9;i++)

{

scanf("%d",&num&lt;i&gt;);

}

//用兩次層for循環來比較數據,進行冒泡

for(j=0;j&lt;9;j++)

{

for(k=0;k&lt;9-j;k++)

{

if(num[k]&lt;num[k+1])//num[k]&lt;num[k+1]

{

temp=num[k];

num[k]=num[k+1];

num[k+1]=temp;

}

}

}

//用一個for循環來輸出數組中排序好的數據

for(l=0;l&lt;=9;l++)

{

printf("%d",num[l]);

}

return 0;

}

(5)c語言非數值的排序擴展閱讀:

return 0代表程序正常退出。return是C++預定義的語句,它提供了終止函數執行的一種方式。當return語句提供了一個值時,這個值就成為函數的返回值。

return語句用來結束循環,或返回一個函數的值。

1、return 0,說明程序正常退出,返回到主程序繼續往下執行。

2、return 1,說明程序異常退出,返回主調函數來處理,繼續往下執行。return 0或return 1對程序執行的順序沒有影響,只是大家習慣於使用return(0)退出子程序而已。

『陸』 用C語言選擇排序法對字母排序,求大神指導,是對字母排序,不是數字!

你是要在一個.txt中選取單詞還是,終端輸入幾個單詞,再排序
還有你現在不是寫了一個程序了嗎,有什麼問題??

『柒』 C語言選擇排序法有哪些

1、穩定排序和非穩定排序
簡單地說就是所有相等的數經過某種排序方法後,仍能保持它們在排序之前的相對次序,我
們就
說這種排序方法是穩定的。反之,就是非穩定的。
比如:一組數排序前是a1,a2,a3,a4,a5,其中a2=a4,經過某種排序後為a1,a2,a4,a3,a5,
則我們說這種排序是穩定的,因為a2排序前在a4的前面,排序後它還是在a4的前面。假如變
成a1,a4,
a2,a3,a5就不是穩定的了。
2、內排序和外排序
在排序過程中,所有需要排序的數都在內存,並在內存中調整它們的存儲順序,稱為內排序;
在排序過程中,只有部分數被調入內存,並藉助內存調整數在外存中的存放順序排序方法稱
為外排序。
3、演算法的時間復雜度和空間復雜度
所謂演算法的時間復雜度,是指執行演算法所需要的計算工作量。
一個演算法的空間復雜度,一般是指執行這個演算法所需要的內存空間。
======================================================================
==========
*/
/*
================================================
功能:選擇排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================
*/
/*
====================================================
演算法思想簡單描述:
在要排序的一組數中,選出最小的一個數與第一個位置的數交換;
然後在剩下的數當中再找最小的與第二個位置的數交換,如此循環
到倒數第二個數和最後一個數比較為止。
選擇排序是不穩定的。演算法復雜度O(n2)--[n的平方]
=====================================================
*/
voidselect_sort(int*x,intn)
{
inti,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的平方]
=====================================================
*/
voidinsert_sort(int*x,intn)
{
inti,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的平方]
=====================================================
*/
voidbubble_sort(int*x,intn)
{
intj,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。
希爾排序是不穩定的。
=====================================================
*/
voidshell_sort(int*x,intn)
{
inth,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)
=====================================================
*/
voidquick_sort(int*x,intlow,inthigh)
{
inti,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); /*對基準點右邊的數再執行快速排序*/
}
}
/*
================================================
功能:堆排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================

『捌』 C語言非數值演算法

#include<stdio.h>
void
put(char,int,int);
void
main()
{
int
i,j,k,n;
printf
("Input
a
number:
");
/*輸入要求輸出的行數
*/
scanf
("%d",&n);
for(i=0;i<n;i++)
{/*循環輸出N行
*/
if(i>(n-1)/2)
k=n-i-1;
else
k=i;
put('*',(5-2*k-1)/2,k+2);
printf("\n");
}
}
void
put(char
ch,int
sta,int
end)
{
int
i
,j;
for(i=1;i<=sta;++i)
putchar('
');
for(j=sta;j<=end;++j)
putchar(ch);
}
借tg_scorpio
-
魔法師
四級
的代碼用一下。

『玖』 急求:用C語言程序對一組大小不定的數字排序拜託了各位 謝謝

第一個就是冒泡排序法,幾乎是最簡單的排序方法:
#include
<stdio.h>
#include
<conio.h>
#define
N
10
int
main(
void
)
{
int
i,
j,
temp
;
int
a[N]
=
{0,1,2,3,4,5,6,7,8,9};
//
冒泡排序法進行排序
for(
i
=
0;
i
<
N
-
1;
i++
){
for(
j
=
0;
j
<
N-i-1;
j++
){
if(
a[i]
<
a[j]
){
temp
=
a[i]
;
a[i]
=
a[j]
;
a[j]
=
temp
;
}
}
}//第一個for
printf("你是入的十個數是:\n")
;
for(
i
=
0;
i
<
N;
i++
){
printf("%d
",a[i]
)
;
}
getch()
;
return
0
;
}
下面的是選擇排序法,比冒泡排序法的效率高:
#include
<stdio.h>
#include
<conio.h>
#define
N
10
int
main(
void
)
{
int
i,
j,
k,
temp
;
int
a[N]
=
{0,1,2,3,4,5,6,7,8,9};
//
選擇排序法進行排序
for(
i
=
0;
i
<
N
-
1;
i++
){
k
=
i
;
for(
j
=
i
+
1;
j
<
N;
j++
){
if(
a[k]
<
a[j]
){
k
=
j
;
}
temp
=
a[i]
;
a[i]
=
a[k]
;
a[k]
=
temp
;
}
}//第一個for
printf("你是入的十個數是:\n")
;
for(
i
=
0;
i
<
N;
i++
){
printf("%d
",a[i]
)
;
}
getch()
;
return
0
;
}
下面的是插入排序法,比冒泡排序法和選擇排序法的效率都要高:
#include
<stdio.h>
#include
<conio.h>
#define
N
10
int
main(
void
)
{
int
i,
j,
key,
temp
;
int
a[N]
=
{0,1,2,3,4,5,6,7,8,9};
//
插入排序法進行排序
for(
i
=
1;
i
<
N
;
i++
){
key
=
a[i]
;
for(
j
=
i
-
1;
j
>=
0;
j--
){
if(
a[j]
<
key
){
a[j+1]
=
a[j]
;
}
}
a[j+1]
=
key
;
}//第一個for
printf("你是入的十個數是:\n")
;
for(
i
=
0;
i
<
N;
i++
){
printf("%d
",a[i]
)
;
}
getch()
;
return
0
;
}
下面的是歸並排序法,我是在看了《演算法導論》之後才寫的,我自己寫不出來。代碼寫出來很簡單,比其它一些書上的簡單多了。歸並排序法的效率是這四個排序法中效率最高的:
#include
<stdio.h>
#include
<conio.h>
#define
N
10
void
merge_sort(
int
*a,
int
p,
int
q,
int
r
)
{
int
i,
j,
k,
m,
n
;
int
array1[N],
array2[N]
;
//
m和n分別是新建立的兩個數組中
//
元素的個數
m
=
q
-
p
+
1
;
n
=
r
-
q
;
//
先把數組a[N],中的元素放進
//
新建立的兩個數組中
for(
i
=
0;
i
<
m;
i++
){
array1[i]
=
*(
a
+
p
+
i
)
;
}
for(
j
=
0;
j
<
n;
j++
){
array2[j]
=
*(
a
+
q
+
j
+1
)
;
}
i
=
j
=
0
;
k
=
p
;
//
k
不能被初始化為
0
//
開始歸並
while(
i
<
m
&&
j
<
n
){
if(
array1[i]
>
array2[j]
){
*(
a
+
k
)
=
array1[i]
;
++
k
;
++
i
;
}
else{
*(
a
+
k
)
=
array2[j]
;
++
k
;
++
j
;
}
}
//
歸並每個數組剩下的元素
while(
i
<
m
){
*(
a
+
k
)
=
array1[i]
;
++
k
;
++
i
;
}
while(
j
<
n
){
*(
a
+
k
)
=
array2[j]
;
++
k
;
++
j
;
}
}
void
merge(
int
*a,
int
p,
int
r
)
{
int
q
;
//
p
>=
r的情況就是要排序的元素只有一個,
//
也就是說,它已經被排好了
if(
p
<
r
){
q
=
(p
+
r)/2
;
merge(
a,
p,
q
)
;
merge(
a,
q
+
1,
r
);
merge_sort(
a,
p,
q,
r
);
}
}//
merge
int
main(
void
)
{
int
i,
j,
key,
temp
;
int
a[N]
=
{0,1,2,3,4,5,6,7,8,9};
merge(
a,
0,
9)
;
printf("你是入的十個數是:\n")
;
for(
i
=
0;
i
<
10;
i++
){
printf("%d
",a[i]
)
;
}
getch()
;
return
0
;
}

『拾』 基於C語言的幾種排序演算法的分析

相關知識介紹(所有定義只為幫助讀者理解相關概念,並非嚴格定義):
1、穩定排序和非穩定排序
簡單地說就是所有相等的數經過某種排序方法後,仍能保持它們在排序之前的相對次序,我們就
說這種排序方法是穩定的。反之,就是非穩定的。
比如:一組數排序前是a1,a2,a3,a4,a5,其中a2=a4,經過某種排序後為a1,a2,a4,a3,a5,
則我們說這種排序是穩定的,因為a2排序前在a4的前面,排序後它還是在a4的前面。假如變成a1,a4,
a2,a3,a5就不是穩定的了。
2、內排序和外排序
在排序過程中,所有需要排序的數都在內存,並在內存中調整它們的存儲順序,稱為內排序;
在排序過程中,只有部分數被調入內存,並藉助內存調整數在外存中的存放順序排序方法稱為外排序。
3、演算法的時間復雜度和空間復雜度
所謂演算法的時間復雜度,是指執行演算法所需要的計算工作量。
一個演算法的空間復雜度,一般是指執行這個演算法所需要的內存空間。
================================================================================
*/
/*
================================================
功能:選擇排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================
*/
/*
====================================================
演算法思想簡單描述:
在要排序的一組數中,選出最小的一個數與第一個位置的數交換;
然後在剩下的數當中再找最小的與第二個位置的數交換,如此循環
到倒數第二個數和最後一個數比較為止。
選擇排序是不穩定的。演算法復雜度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");
}