當前位置:首頁 » 操作系統 » 無用排序演算法

無用排序演算法

發布時間: 2022-04-30 20:33:15

㈠ 排序演算法課程設計

// 各種排序演算法匯總.cpp : 定義控制台應用程序的入口點。
//
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;

#include <stack>
#include <time.h>
#include <stdlib.h>

template < typename T >
class SqList
{
private:
int length;
T * r;
public://介面
SqList(int n = 0);//構造長度為n的數組
~SqList()
{
length = 0;
delete r;
r = NULL;
}
void InsertSort();//順序插入排序
void DisPlay();//輸出元素
void BInsertSort();//折半插入排序
void ShellSort(int dlta[],int t);//希爾排序
void QuickSort();//快速排序
void SelectSort();//簡單選擇排序
void BubbleSort();//改進冒泡排序
void Bubble_Sort2();//相鄰兩趟是反方向起泡的冒泡排序演算法
void Bubble_Sort3();//對相鄰兩趟反方向演算法進行化簡,循環體中只包含一次冒泡
void HeapSort();//堆排序
void Build_Heap_Sort();//堆排序由小到大序號建立大根堆
void MergeSort();//歸並排序
void OE_Sort();//奇偶交換排序的演算法

void Q_Sort_NotRecurre();//非遞歸快速排序
void HeapSort_3();//三叉堆排序

public://調用
void ShellInsert(int dk);//一趟希爾排序
void QSort(int low,int high);//快速排序
int Partition(int low,int high);//一趟快速排序
int SelectMinKey(int i);//從i到length中選擇最小值下標
void HeapAdjust(int s,int m);//調整s的位置,其中s+1~m有序
void HeapAdjust_3(int s,int m);//三叉堆****調整s的位置,其中s+1~m有序
void Merge(T SR[],T TR[],int i,int m,int n);//歸並
void MSort(T SR[],T TR1[],int s,int t);//歸並
void Easy_Sort(int low,int high);//3個數直接排序
void Build_Heap(int len);//從低下標到高下標逐個插入建堆的演算法***建立大根堆**但為排序

};
template < typename T >
SqList<T>::SqList(int n = 0)
{
//srand( time(0) );
length = n;
r=new T[length+1];
T t;
cout<<"隨機生成"<<n<<"個值:"<<endl;
for (int i=1;i<=length;i++)
{
//cin>>t;
r[i] = rand()%1000;
//r[i] = t;
}
for (int i=1; i<=length;i++)
cout<<r[i]<<",";
cout<<endl;
}
template < typename T >
void SqList<T>::InsertSort()
{
int i,j;
for (i=2;i<=length;i++)
{
if (r[i]<r[i-1])
{
r[0]=r[i];
r[i]=r[i-1];
for (j=i-2;r[0]<r[i-2];j--)
r[j+1]=r[j];
r[j+1]=r[0];
}
}
}
template < typename T >
void SqList<T>::DisPlay()
{
int i;
cout<<length<<" 元素為:"<<endl;
for (i = 1;i < length+1;i++ )
{
cout<<r[i]<<" ,";
}
cout<<endl;
}
template < typename T >
void SqList<T>::BInsertSort()
{
int i, j, m;
int low,high;
for (i = 2;i<= length;i++)
{
r[0]=r[i];
low=1;
high=i-1;
while (low<=high)
{
m = (low+high)/2;
if ( r[0] < r[m] )
high=m-1;
else
low=m+1;
}
for ( j=i-1;j >=high+1; j--)
{
r[j+1] = r[j];
}
r[high+1] = r[0];
}
}

template < typename T >
void SqList<T>::ShellInsert(int dk)
{
int i,j;
for (i=dk+1;i<=length;i++)
if (r[i] < r[i-dk])
{
r[0] = r[i];
for ( j=i-dk; j>0 && r[0] < r[j]; j-=dk)
{
r[j+dk]=r[j];
}
r[j+dk] = r[0];
}
}
template < typename T >
void SqList<T>::ShellSort(int dlta[],int t)
{
int k=0;
for (;k<t;k++)
{
ShellInsert(dlta[k]);
}
}
template < typename T >
int SqList<T>::Partition(int low,int high)
{
int pivotkey;
r[0] = r[low];//記錄樞軸值
pivotkey = r[low];
while (low < high)
{
while (low < high&& r[high] >= pivotkey)
high--;
r[low] = r[high];
while (low < high&& r[low] <= pivotkey)
low++;
r[high] = r[low];
}
r[low] = r[0];//樞軸記錄到位
return low;//返回樞軸位置
}
template < typename T >
void SqList<T>::QSort(int low,int high)
{
int pivotloc;
if (low < high)
{
pivotloc = Partition(low,high);
QSort(low,pivotloc-1);
QSort(pivotloc+1,high);
}
}
template < typename T >
void SqList<T>::QuickSort()
{
QSort(1,length);
}
template < typename T >
int SqList<T>::SelectMinKey(int i)
{
int j,min=i;
for (j=i;j <= length;j++)
{
if (r[min] > r[j])
{
min = j;
}
}
return min;
}
template < typename T >
void SqList<T>::SelectSort()
{
int i,j;
T t;
for (i=1;i < length;i++)//循環length-1次不是length次
{
j=SelectMinKey(i);
if (i != j)
{
t= r[j];
r[j]=r[i];
r[i]=t;
}
}
}
template < typename T >
void SqList<T>::BubbleSort()
{
int i,j;
int flag=1;//標識位,如果出現0,則沒有交換,立即停止
T t;
for (i=1;i < length && flag;i++)
{
flag = 0;
for (j=length-1;j>=i;j--)
if (r[j]>r[j+1])
{
t=r[j];
r[j]=r[j+1];
r[j+1]=t;
flag=1;
}
}
}
template < typename T >
void SqList<T>::Bubble_Sort2()
{
bool change = true;
int low = 1, high = length;
int i;
T t;
while ( (low < high) && change )
{
change = false;
for ( i = low; i < high; i++ )
{
if ( r[i] > r[i+1] )
{
t = r[i];
r[i] = r[i+1];
r[i+1] = t;
change = true;
}
}
high-=1;
for ( i = high; i > low; i-- )
{
if ( r[i] < r[i-1] )
{
t = r[i];
r[i] = r[i-1];
r[i-1] = t;
change = true;
}
}
low+=1;
}
}

template < typename T >
void SqList<T>::Bubble_Sort3()
{
int i,d=1;
bool change = true;
int b[3] = {1,0,length};//b[0]為冒泡的下界,b[ 2 ]為上界,b[1]無用
T t;
while (change)//如果一趟無交換,則停止
{
change = false;
for ( i=b[1-d]; i!=b[1+d]; i=i+d )//統一的冒泡演算法
{
if ( (r[i]-r[i+d])*d > 0 )///注意這個交換條件
{
t = r[i];
r[i] = r[i+d];
r[i+d] = t;
change = true;
}
}
d = d*(-1);//換個方向
}
}
template < typename T >
void SqList<T>::HeapAdjust(int s,int m)
{
/* 已知H.r[s..m]中記錄的關鍵字除H.r[s].key之外均滿足堆的定義,本函數 */
/* 調整H.r[s]的關鍵字,使H.r[s..m]成為一個大頂堆(對其中記錄的關鍵字而言) */
int j;
T rc = r[s];
for (j=2*s;j <= m;j*=2)
{
/* 沿key較大的孩子結點向下篩選 */
if (j < m && r[j] < r[j+1])
j++;/* j為key較大的記錄的下標 */
if (rc >= r[j])
break;/* rc應插入在位置s上 ,無需移動*/
r[s]=r[j];
s=j;
}
r[s]=rc;/* 插入 */
}
template < typename T >
void SqList<T>::HeapSort()
{
/* 對順序表H進行堆排序。演算法10.11 */
T t;
int i;
for (i=length/2;i>0;i--)/* 把H.r[1..H.length]建成大頂堆 */
HeapAdjust(i,length);
for (i=length;i>1;i--)
{
/* 將堆頂記錄和當前未經排序子序列H.r[1..i]中最後一個記錄相互交換 */
t=r[1];
r[1]=r[i];
r[i]=t;
HeapAdjust(1,i-1);/* 將H.r[1..i-1]重新調整為大頂堆 */
}
}
template < typename T >
void SqList<T>::Build_Heap_Sort()
{
int i;
Build_Heap(length);
for ( i = length; i > 1; i-- )
{
T t;
t = r[i];
r[i] = r[1];
r[1] = t;
Build_Heap(i-1);
}

}
template < typename T >
void SqList<T>::Build_Heap(int len)
{
T t;
for (int i=2; i <= len; i++ )
{
int j = i;
while ( j != 1 )
{
int k = j/2;
if ( r[j] > r[k] )
{
t = r[j];
r[j] = r[k];
r[k] = t;
}
j = k;
}
}

}
template < typename T >
void SqList<T>::Merge(T SR[],T TR[],int i,int m,int n)
{
/* 將有序的SR[i..m]和SR[m+1..n]歸並為有序的TR[i..n] 演算法10.12 */
int j,k,x;
for (j=m+1,k=i;j<=n&&i<=m;k++)/* 將SR中記錄由小到大地並入TR */
{
if (SR[i]<SR[j])
TR[k]=SR[i++];
else
TR[k]=SR[j++];
}
if (i<=m)
for (x=0;x<=m-i;x++)
TR[k+x]=SR[i+x];/* 將剩餘的SR[i..m]復制到TR */
if (j<=n)
for (x=0;x<=n-j;x++)
TR[k+x]=SR[j+x];/* 將剩餘的SR[j..n]復制到TR */
}
template < typename T >
void SqList<T>::MSort(T SR[],T TR1[],int s,int t)
{
/* 將SR[s..t]歸並排序為TR1[s..t]。演算法10.13 */
int m;
T *TR2=new T[length+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] */
}
}
template < typename T >
void SqList<T>::MergeSort()
{
MSort(r,r,1,length);
}
template < typename T >
void SqList<T>::OE_Sort()
{
int i;
T t;
bool change = true;
while ( change )
{
change = false;
for ( i=1;i<length;i+=2 )
{
if (r[i] > r[i+1])
{
t = r[i];
r[i] = r[i+1];
r[i+1] = t;
change = true;
}
}
for ( i=2;i<length;i+=2 )
{
if ( r[i] > r[i+1] )
{
t = r[i];
r[i] = r[i+1];
r[i+1] = t;
change = true;
}
}

}

}
typedef struct
{
int low;
int high;
}boundary;
template <typename T >
void SqList<T>::Q_Sort_NotRecurre()
{
int low=1,high=length;
int piv;
boundary bo1,bo2;
stack<boundary> st;
while (low < high)
{
piv = Partition(low,high);
if ( (piv-low < high-piv) && (high-piv > 2) )
{
bo1.low = piv+1;
bo1.high = high;
st.push(bo1);
high = piv-1;
}
else if ( (piv-low > high-piv) && (piv-low >2) )
{
bo1.low = low;
bo1.high = piv-1;
st.push(bo1);
low = piv+1;
}
else
{
Easy_Sort(low,high);
high = low;
}
}
while ( !st.empty() )
{
bo2 = st.top();
st.pop();
low = bo2.low;
high = bo2.high;
piv = Partition(low, high);
if ( (piv-low < high-piv) && (high-piv > 2) )
{
bo1.low = piv+1;
bo1.high = high;
st.push(bo1);
high = piv-1;
}
else if ( (piv-low > high-piv) && (piv-low >2) )
{
bo1.low = low;
bo1.high = piv-1;
st.push(bo1);
low = piv+1;
}
else
{
Easy_Sort(low,high);
}
}

}
template < typename T >
void SqList<T>::Easy_Sort(int low,int high)
{
T t;
if ( (high-low) == 1 )
{
if ( r[low] > r[high] )
{
t = r[low];
r[low] = r[high];
r[high] = t;
}
}
else
{
if ( r[low] > r[low+1] )
{
t = r[low];
r[low] = r[low+1];
r[low+1] = t;
}
if ( r[low+1] > r[high] )
{
t = r[low+1];
r[low+1] = r[high];
r[high] = t;
}
if ( r[low] > r[low+1] )
{
t = r[low];
r[low] = r[low+1];
r[low+1] = t;
}
}

}

template < typename T >
void SqList<T>::HeapAdjust_3(int s,int m)
{
T rc = r[s];
for (int j = 3*s-1; j <= m;j=j*3-1)
{
if (j+1<m)//有3個孩子結點
{
if ( rc>=r[j] && rc>=r[j+1] && rc>=r[j+2] )
break;
else
{
if ( r[j] > r[j+1] )
{
if ( r[j] > r[j+2] )
{
r[s]=r[j];
s=j;
}
else//r[j]<=r[j+2]
{
r[s]=r[j+2];
s=j+2;
}
}
else//r[j]<=r[j+1]
{
if ( r[j+1] > r[j+2] )
{
r[s]=r[j+1];
s=j+1;
}
else//r[j+1]<=r[j+2]
{
r[s]=r[j+2];
s=j+2;
}
}
}
}
if ( j+1==m )//有2個孩子結點
{
if ( rc>=r[j] && rc>=r[j+1] )
break;
else
{
if ( r[j] > r[j+1] )
{
r[s]=r[j];
s=j;
}
else//r[j]<=r[j+1]
{
r[s]=r[j+1];
s=j+1;
}
}
}
if (j==m)//有1個孩子結點
{
if ( rc>=r[j] )
break;
else
{
r[s]=r[j];
s=j;
}
}
}
r[s]=rc;
}

template <typename T >
void SqList<T>::HeapSort_3()
{
int i;
T t;
for (i=length/3; i>0; i--)
HeapAdjust_3(i,length);
for ( i=length; i > 1; i-- )
{
t = r[i];
r[i] = r[1];
r[1] = t;
HeapAdjust_3(1,i-1);
}
}

int _tmain(int argc, _TCHAR* argv[])
{
SqList<int> Sq(15);
//Sq.InsertSort();
//Sq.BInsertSort();
/* 希爾排序*/
// int a[5]={5,4,3,2,1};
// Sq.ShellSort(a,5);

/* Sq.QuickSort();*/

// Sq.SelectSort();

/* Sq.BubbleSort();*/

/* Sq.HeapSort();*/

/* Sq.MergeSort();*/

/* Sq.Q_Sort_NotRecurre();*/

/* Sq.Bubble_Sort2();*/
/* Sq.OE_Sort();*/
/* Sq.Bubble_Sort3();*/

/* Sq.Build_Heap_Sort();*/

Sq.HeapSort_3();

Sq.DisPlay();
system("pause");
return 1;
}

㈡ 演算法如何刷題

1、原題
我自己感覺原題的概率還是挺大的,特別是劍指offer的66題更是如此。千萬別小看這66題,這幾十道題裡面基本所有的演算法類型都有包括在內,常用的數據結構,操作方式,常用演算法思路都有不少的題。

如果真的能夠充分理解這幾十道題的最優解,我感覺其實已經形成基本的演算法思維了。

另外,leetcode的原題也很常見,因為LC本身題量大,在裡面出原題不是為了考倒你,而是檢驗你的刷題質量。

畢竟那些大公司面試官也不是傻子,知道你在面試前肯定會大規模刷題的。所以把刷過的題完全搞懂才是最重要的。

2、改編題
改編題就很顯而易見了。改編題大多需要從基本的演算法原理中找到處理的思維,然後結合實際題干進行性能優化,就能夠搞定。

這里要記得一點的是,正常的演算法考察不會故意刁難你(正常情況),也不會給過多的時間讓你思考和敲代碼。

所以遇到改編題不要想得太復雜,盡量要找到它的演算法思維是什麼。怎麼說呢,透過現象看本質。我總結的改編題有以下幾種思路:

1)新的數據結構,換湯不換葯。比如最常見的排序演算法的改編,原來是對數字進行排序,現在對鏈表排序等等。比較難一點的可能會遇到自定義的數據結構。但是演算法本質不會變。

2)演算法類型改編。

這里要說的就是一個比較大的范圍,比如動態規劃、貪心演算法、遞歸、回溯和分治等等。這種是從演算法大的類型上進行改編,很難用相同的套路去解題。

遇到這類題的關鍵就是要先弄明白演算法核心。比如動態規劃的狀態方程,貪心演算法的局部最優情況,遞歸回溯的邊界判斷,分治的子問題劃分等等。這種類型的確比較難把握,怎麼碩呢,每種類型的都來搞幾道感覺感覺吧。

3)添加應用題背景。

這種題目看起來不難,但是難就難在對應用題背景的理解,需要去理解題意,然後考慮合適的數據結構和處理演算法。這裡面有數學建模的思維在裡面,需要把一堆無用的信息剔除,篩選出有效的信息,然後才能選擇正確的演算法。

3、創新題
這類題考察的是你的擴展思維,如果說上面的題考查的是你的思維深度,這種題就是考察演算法的廣度。可能一看題目,完全沒見過這種類型。但是演算法本身其實不就是讓計算機代替人腦進行高重復性的計算嘛。

首先你需要想到你應該去怎麼算這個題,然後再換到計算機上,會發生什麼問題(空間時間問題,運行效率,代碼冗餘等等),之後再想通過經典的演算法原理來解決這些

1、題型分類
按照個人的習慣,喜歡按照一種類型狂刷,然後再刷另外一種類型。一般常見的演算法類型可分為:

數組、鏈表

包含基本排序演算法、二分查找、鏈表的一系列操作。

棧、隊列、堆

利用棧、隊列互相實現,堆的使用

二叉樹與圖

主要是遍歷演算法和節點的計算:
二叉樹四種遍歷方式、廣度優先遍歷(BFS)和廣度優先遍歷(DFS),節點到節點距離等等。

哈希表

使用標准庫自帶的模板或者函數就很簡單了,一般會與其它數據結構相結合來提升時間復雜度。

字元串操作

字元串的操作也很多,本質上可以看作是數組的操作。另外字元串的一些匹配和尋求字串的演算法還是非常具有思考價值的。KMP,馬拉車等等。

遞歸

重點掌握邊界判斷條件。

回溯

重點掌握邊界判斷條件。

分治

重點掌握如何劃分子問題。

動態規劃

題太多了,可從一階dp到二階dp理解不同的狀態方程。

貪心及其它

這個就很容易理解了,遇到貪心題應該要偷笑了。

2、高頻熱點多刷
這不多說了吧,Leetcode熱題HOT 100。你值得擁有。

在不知道怎麼刷的情況下,不如先刷起來。刷個題沒那麼多捷徑,只有堅持刷起來了,才會形成自己的思維方式和學習習慣。

我建議是先按照類型刷,每個類型刷十幾二十道。然後打混按照演算法熱度排序重新查漏補缺。

3、思路回顧
許多同學在一股腦刷了很多題之後,再看做過的題會發現忘了不少。可能大家都是這樣的吧。我覺得是因為在刷題的時候過於心急,理解了大概就過了,或者類型做的太雜,沒有留下印象。

我比較喜歡的方式是偶爾會重新看看曾經做過的題,就看題目然後想思路,再畫一畫步驟演進,沒時間就不細敲了。這樣可以增強一下思維記憶,之前理解過的東西,再回憶起來還是非常快的。

㈢ 用c語言寫一個數組從小到大輸出

這是一種最原始的排序演算法,比較接近於選擇排序,即每次選出一個最小的元素放到a[i]的位置,然後對a[i+1]~a[9]的元素再重復上述操作,直到完成整個排序過程。但是這個排序演算法做了很多無用的交換操作,浪費了很多時間。對這個循環過程進行改進可以變成標準的選擇排序或是冒泡排序。

㈣ [在線等]冒泡排序演算法的一些疑問(C語言) #include <stdio.h

一 先說簡單的,最後的Return 1
1,為什麼需要Return ,因為是int main() 是有返回值的函數
2, Return後面應該寫多少.這分兩情況,如果有其它地方對你的返回值有興趣,你就要按約定的意義來寫,如果沒有任何地方對你的返回值有興趣,那你寫幾都可以.

二 再說說那個flag
1,這里為什麼要加這個標志位呢?
程序的設計思想是好的,通過增加這個標志位,已減少不必要的計算.看個例子:
如果你輸入:2 1 3 4 5 6 7 8 9 10 這時候,我們只需要改變2和1的位置,就排好序了.你現在的代碼是按從小到大排序,冒泡排序就是每次循環中在剩餘數中找到最小的那個放到對應的位置.
如果沒有flag這個變數,在第一次循環中,把1放到了最前面,程序還會去接著循環8次,對後面的數進行排序,這其實就是無用操作,因為後面的已經排好序了.
2,flag起到這個作用了嗎?
沒有,因為代碼寫的有問題,沒有達到這個目標,以現在的代碼,只有輸入的數是:1 2 3 4 5 6 7 8 9 10
才會執行到break這里,跳出循環:
if(flag==1)
{
break;
}
而對:2 1 3 4 5 6 7 8 9 10這種輸入就沒有作用了,因為在第一次循環中,它就把flag的值改成0了,它永遠也不會==1,所以代碼要改成這樣
if(flag==1)
{
break;
}
flag = 1;

好,就這么多了,其它你自己想去吧

㈤ 誰幫我寫一份c語言版的各種排序演算法的效率比較

(1)「冒泡法」 冒泡法大家都較熟悉。其原理為從a[0]開始,依次將其和後面的元素比較,若a[0]>a[i],則交換它們,一直比較到a[n]。同理對a[1],a[2],...a[n-1]處理,即完成排序。下面列出其代碼:void bubble(int *a,int n) /*定義兩個參數:數組首地址與數組大小*/ { int i,j,temp; for(i=0;i<n-1;i++) for(j=i+1;j<n;j++) /*注意循環的上下限*/ if(a[i]>a[j]) { temp=a[i]; a[i]=a[j]; a[j]=temp; } } 冒泡法原理簡單,但其缺點是交換次數多,效率低。 下面介紹一種源自冒泡法但更有效率的方法「選擇法」。 (2)「選擇法」 選擇法循環過程與冒泡法一致,它還定義了記號k=i,然後依次把a[k]同後面元素比較,若a[k]>a[j],則使k=j.最後看看k=i是否還成立,不成立則交換a[k],a[i],這樣就比冒泡法省下許多無用的交換,提高了效率。void choise(int *a,int n) { int i,j,k,temp; for(i=0;i<n-1;i++) { k=i; /*給記號賦值*/ for(j=i+1;j<n;j++) if(a[k]>a[j]) k=j; /*是k總是指向最小元素*/ if(i!=k) { /*當k!=i是才交換,否則a[i]即為最小*/ temp=a[i]; a[i]=a[k]; a[k]=temp; } } } 選擇法比冒泡法效率更高,但說到高效率,非「快速法」莫屬,現在就讓我們來了解它。 (3)「快速法」 快速法定義了三個參數,(數組首地址*a,要排序數組起始元素下標i,要排序數組結束元素下標j). 它首先選一個數組元素(一般為a[(i+j)/2],即中間元素)作為參照,把比它小的元素放到它的左邊,比它大的放在右邊。然後運用遞歸,在將它左,右兩個子數組排序,最後完成整個數組的排序。下面分析其代碼:void quick(int *a,int i,int j) { int m,n,temp; int k; m=i; n=j; k=a[(i+j)/2]; /*選取的參照*/ do { while(a[m]<k&&m<j) m++; /* 從左到右找比k大的元素*/ while(a[n]>k&&n>i) n--; /* 從右到左找比k小的元素*/ if(m<=n) { /*若找到且滿足條件,則交換*/ temp=a[m]; a[m]=a[n]; a[n]=temp; m++; n--; } }while(m<=n); if(m<j) quick(a,m,j); /*運用遞歸*/ if(n>i) quick(a,i,n); } (4)「插入法」 插入法是一種比較直觀的排序方法。它首先把數組頭兩個元素排好序,再依次把後面的元素插入適當的位置。把數組元素插完也就完成了排序。void insert(int *a,int n) { int i,j,temp; for(i=1;i<n;i++) { temp=a[i]; /*temp為要插入的元素*/ j=i-1; while(j>=0&&temp<a[j]) { /*從a[i-1]開始找比a[i]小的數,同時把數組元素向後移*/ a[j+1]=a[j]; j--; } a[j+1]=temp; /*插入*/ } } (5)「shell法」 shell法是一個叫 shell 的美國人與1969年發明的。它首先把相距k(k>=1)的那幾個元素排好序,再縮小k值(一般取其一半),再排序,直到k=1時完成排序。下面讓我們來分析其代碼:void shell(int *a,int n) { int i,j,k,x; k=n/2; /*間距值*/ while(k>=1) { for(i=k;i<n;i++) { x=a[i]; j=i-k; while(j>=0&&x<a[j]) { a[j+k]=a[j]; j-=k; } a[j+k]=x; } k/=2; /*縮小間距值*/ } } 上面我們已經對幾種排序法作了介紹,現在讓我們寫個主函數檢驗一下。 #include<stdio.h> /*別偷懶,下面的"..."代表函數體,自己加上去哦!*/ void bubble(int *a,int n) { ... } void choise(int *a,int n) { ... } void quick(int *a,int i,int j) { ... } void insert(int *a,int n) { ... } void shell(int *a,int n) { ... } /*為了列印方便,我們寫一個print吧。*/[code]void print(int *a,int n) { int i; for(i=0;i<n;i++) printf("%5d",a[i]); printf("\n"); } main() { /*為了公平,我們給每個函數定義一個相同數組*/ int a1[]={13,0,5,8,1,7,21,50,9,2}; int a2[]={13,0,5,8,1,7,21,50,9,2}; int a3[]={13,0,5,8,1,7,21,50,9,2}; int a4[]={13,0,5,8,1,7,21,50,9,2}; int a5[]={13,0,5,8,1,7,21,50,9,2}; printf("the original list:"); print(a1,10); printf("according to bubble:"); bubble(a1,10); print(a1,10); printf("according to choise:"); choise(a2,10); print(a2,10); printf("according to quick:"); quick(a3,0,9); print(a3,10); printf("according to insert:"); insert(a4,10); print(a4,10); printf("according to shell:"); shell(a5,10); print(a5,10); }

㈥ 請給我詳細解釋一下這段程序 謝謝了!!!C語言的!

這是一個數組的冒泡排序演算法。
void fun(int bb[], int n)
{
int i, j, t;//i,j作為數組下標變數,t用於交換兩個數時的臨時變數
for (i=0; i<n; i++)
for (j=0; j<n-1; j++)
if (bb[j] > bb[j+1])//比較兩個數,如果第一個數大於第二個數,則交換它們
{
t = bb[j];//這三行是交換兩個數
bb[j] = bb[j+1];
bb[j+1] = t;
}
}
冒泡演算法顧名思義,就是讓最小的數一點一點被換到最前面來,當然如果比較的時候if (bb[j] > bb[j+1])這里用的是小於,那就是小的一點點被交換到後面去。
程序開始的時候首先讓數組的第一個數和第二個數比較,如果第一個數較大,則交換它們,以此類推,把最大的一個數交換到最後,然後再找前面剩下的最大數放到倒數第二個位置,如此循環下去,直到循環完成,數組也就排序完成了。

對問題補充的回答:
樓主的這個演算法還可以再優化一下,比如該數組一開始是:
5,2,4,8,9,7這樣,
第一次內部循環開始,
j=0,5>2成立,所以交換,變成
2,5,4,8,9,7
j=1,5>4成立,所以交換,變成
2,4,5,8,9,7
j=2,5>8不成立,所以不用交換
2,4,5,8,9,7
j=3,8>9不成立,所以不用交換
2,4,5,8,9,7
j=4,9>7成立,所以交換,變成
2,4,5,8,7,9
第一次循環結束,把最大的9換到了最後。接下來還要依次找出第二大的,第三大的。。直到5次後,最終變成:
2,4,5,7,8,9,這就是第一個循環for (i=0; i<n; i++)的作用,因為一次內部循環只能把最大的第一個數交換到最後去,但是前面的還沒有完成排序,所以總共需要數組個數的次數才能確保交換完畢。
其實上面這個數組還可以看出,外層循環只要運行兩次,也就是當i=2的時候,數組就已經是按從小大大排列好了,所以,它有很多的時間都在做無用功。不管給定的數組是什麼樣的順序,它都要做完雙重循環,其實我們完全可以在程序中增加判斷,如果內部循環一次下來,沒有發生過交換,就說明,數組已經是排序好了,這時候就可以終止程序了,這樣可以提高程序的效率,以下是優化過的冒泡排序演算法:

#define bool int
#define false 0
#define true 1
void funSort(int aa[],int n)
{
int iCount=0;//用來記錄排序所用次 數
int i,j,t;//i,j為數組下標變數,t為交換臨時變數
bool bChange;//用來記錄內層循環是否發生過交換,如果沒有發生過交換,則說明數組已經是有序的,就可以終止排序了。
for(i=0;i<n;i++)//總共需要n次外層循環
{
bChange=false;//初值為false,沒有發生過交換
for(j=n-1;j>0;j--)//從後往前比較,把最小的交換到前面去,就像氣泡一樣,冒到最上面。
{
iCount++;//循環計數器加1
if(aa[j]<aa[j-1])
{
bChange=true;//發生過交換,則繼續比較
t=aa[j];//以下三行交換兩個數
aa[j]=aa[j-1];
aa[j-1]=t;
}
}
if(!bChange) break;//如果沒有發生過交換,則終止排序
}
printf("排序比較總次數:%d\n",iCount);//顯示排序所用的次數
}

樓主可以自己在電腦上試一下,先輸入一個已經排序好的數組(最好情況),看看排序總共進行了多少次比較,再輸入一個逆序的數組(最壞情況),再看看進行了多少次比較.
還有不明白的,再交流,呵呵。可以發網路H消息給我。

㈦ 如何在現代C中實現經典排序演算法

冒泡法大家都較熟悉。其原理為從a[0]開始,依次將其和後面的元素比較,若a[0]>a[i],則交換它們,一直比較到a[n]。同理對a[1],a[2],...a[n-1]處理,即完成排序。下面列出其代碼:
void bubble(int *a,int n) /*定義兩個參數:數組首地址與數組大小*/
{
int i,j,temp;
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++) /*注意循環的上下限*/
if(a[i]>a[j]) {
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
冒泡法原理簡單,但其缺點是交換次數多,效率低。
下面介紹一種源自冒泡法但更有效率的方法「選擇法」。
(2)「選擇法」
選擇法循環過程與冒泡法一致,它還定義了記號k=i,然後依次把a[k]同後面元素比較,若a[k]>a[j],則使k=j.最後看看k=i是否還成立,不成立則交換a[k],a[i],這樣就比冒泡法省下許多無用的交換,提高了效率。
void choise(int *a,int n)
{
int i,j,k,temp;
for(i=0;i<n-1;i++) {
k=i; /*給記號賦值*/
for(j=i+1;j<n;j++)
if(a[k]>a[j]) k=j; /*是k總是指向最小元素*/
if(i!=k) { /*當k!=i是才交換,否則a[i]即為最小*/
temp=a[i];
a[i]=a[k];
a[k]=temp;
}
}
}
選擇法比冒泡法效率更高,但說到高效率,非「快速法」莫屬,現在就讓我們來了解它。
(3)「快速法」
快速法定義了三個參數,(數組首地址*a,要排序數組起始元素下標i,要排序數組結束元素下標j). 它首先選一個數組元素(一般為a[(i+j)/2],即中間元素)作為參照,把比它小的元素放到它的左邊,比它大的放在右邊。然後運用遞歸,在將它左,右兩個子數組排序,最後完成整個數組的排序。下面分析其代碼:
void quick(int *a,int i,int j)
{
int m,n,temp;
int k;
m=i;
n=j;
k=a[(i+j)/2]; /*選取的參照*/
do {
while(a[m]<k&&m<j) m++; /* 從左到右找比k大的元素*/
while(a[n]>k&&n>i) n--; /* 從右到左找比k小的元素*/
if(m<=n) { /*若找到且滿足條件,則交換*/
temp=a[m];
a[m]=a[n];
a[n]=temp;
m++;
n--;
}
}while(m<=n);
if(m<j) quick(a,m,j); /*運用遞歸*/
if(n>i) quick(a,i,n);
}
(4)「插入法」
插入法是一種比較直觀的排序方法。它首先把數組頭兩個元素排好序,再依次把後面的元素插入適當的位置。把數組元素插完也就完成了排序。
void insert(int *a,int n)
{
int i,j,temp;
for(i=1;i<n;i++) {
temp=a[i]; /*temp為要插入的元素*/
j=i-1;
while(j>=0&&temp<a[j]) { /*從a[i-1]開始找比a[i]小的數,同時把數組元素向後移*/
a[j+1]=a[j];
j--;
}
a[j+1]=temp; /*插入*/
}
}
(5)「shell法」
shell法是一個叫 shell 的美國人與1969年發明的。它首先把相距k(k>=1)的那幾個元素排好序,再縮小k值(一般取其一半),再排序,直到k=1時完成排序。下面讓我們來分析其代碼:
void shell(int *a,int n)
{
int i,j,k,x;
k=n/2; /*間距值*/
while(k>=1) {
for(i=k;i<n;i++) {
x=a[i];
j=i-k;
while(j>=0&&x<a[j]) {
a[j+k]=a[j];
j-=k;
}
a[j+k]=x;
}
k/=2; /*縮小間距值*/
}
}
上面我們已經對幾種排序法作了介紹,現在讓我們寫個主函數檢驗一下。
#include<stdio.h>
/*別偷懶,下面的"..."代表函數體,自己加上去哦!*/
void bubble(int *a,int n)
{
...
}
void choise(int *a,int n)
{
...
}
void quick(int *a,int i,int j)
{
...
}
void insert(int *a,int n)
{
...
}
void shell(int *a,int n)
{
...
}
/*為了列印方便,我們寫一個print吧。*/[code]
void print(int *a,int n)
{
int i;
for(i=0;i<n;i++)
printf("%5d",a[i]);
printf("\n");
}
main()
{ /*為了公平,我們給每個函數定義一個相同數組*/
int a1[]={13,0,5,8,1,7,21,50,9,2};
int a2[]={13,0,5,8,1,7,21,50,9,2};
int a3[]={13,0,5,8,1,7,21,50,9,2};
int a4[]={13,0,5,8,1,7,21,50,9,2};
int a5[]={13,0,5,8,1,7,21,50,9,2};
printf("the original list:");
print(a1,10);
printf("according to bubble:");
bubble(a1,10);
print(a1,10);
printf("according to choise:");
choise(a2,10);
print(a2,10);
printf("according to quick:");
quick(a3,0,9);
print(a3,10);
printf("according to insert:");
insert(a4,10);
print(a4,10);
printf("according to shell:");
shell(a5,10);
print(a5,10);
}

㈧ c++基數排序演算法的問題

寫得很復雜啊!

更改後如下:

#include<iostream>
#include<math.h>
using namespace std;
struct Node{
int data;
Node *prior;
Node *next;
};

void createlinklist(Node* &L){
Node *p;
Node *q;
L=new Node;
L->next=NULL;
L->prior=NULL;

//q=new Node; /* 無用 zhjiemm */

//p = new Node; /* 無用 zhjiemm */
//p->next=NULL; /* 無用 zhjiemm */

int adata=0;
q=L;
while(adata!=-1){
p= new Node;
p->data=adata;
p->prior=NULL;
p->next=NULL;

p->prior=q;
q->next=p;
q=p;
cin>>adata;
if(adata==-1){
L=L->next;
q->next=L;
L->prior=q;

}
}
}
//****************************************************
//子函數
// getNode()
Node* getNode(Node* &L){ /********** 全部改寫 ********** zhjiemm */
Node *p;
p=L->next;
if(p!=L){
L->next = p->next;
p->next->prior = L;
}else{
p=NULL;
}
return p;
}
//getNumber()
int getNumber(Node *p,int i){
int pdata,k;
pdata=p->data;
k=(int)(pdata/pow(10,i));
return k%10;
}
//addNode()
void addNode(Node* &lhead,Node *p){
p->prior=lhead->prior;
p->next=lhead;
lhead->prior->next=p;
lhead->prior=p;

}
//append()
void append(Node* &L,Node* lhead){
if(lhead->next != lhead){//不為空
L->prior->next=lhead->next; /********** 指針指錯了 ********** zhjiemm */
lhead->next->prior=L->prior;
lhead->prior->next=L;
L->prior=lhead->prior;
}
}
//****************************************************
//基數排序主函數
void radix_sort(Node *&L,int k){
Node *Lhead[10],*p;
int i,j,flag;
cout<<"*****\n";
for(i=0;i<10;i++)
Lhead[i]=new Node;

for(i=0;i<k;i++){//第倒數k(位)輪
for(j=0;j<10;j++)//清空
Lhead[j]->next=Lhead[j]->prior=Lhead[j];

while(L->next!=L){//L中的數放入lhead[n]中
p=getNode(L);
if(p) /********** 判斷一下不為空 ********** zhjiemm */
{
flag=getNumber(p,i);//第n輪,取倒數第n位數
addNode(Lhead[flag],p);
}
}
for(int m=0;m<10;m++)//將lhead[n]中的數放入L中
append(L,Lhead[m]);
}

}

int main()
{
Node *L;
createlinklist(L);
radix_sort(L,4);
Node *p=L->next; /* 初始值不對 zhjiemm */
while(p!=L){
cout<<p->data<<" ";
p=p->next;

}

return 0;
}

註:使用完鏈表後,要記得釋放。

㈨ 冒泡排序演算法

DATA SEGMENT
NUM DB 32H , 43H , 23H , 54H , 76H , 45H , 24H , 78H ; 自己添加數
N = $ - NUM
DATA ENDS

STACK SEGMENT STACK
DB 200 DUP(0)
STACK ENDS

CODE SEGMENT
ASSUME CS:CODE , DS:DATA , SS:STACK
START :
MOV AX , DATA
MOV DS , AX
LEA BX , NUM
MOV SI , N
CALL SORT
MOV AH , 4CH
INT 21H
; 子程序名: SORT
; 功能:將8位無符號的二進制數按遞增順序排列
; 入口參數:BX---存放待排數組存貯區首址
; 入口參數:SI---存放待排序數的個數
; 出口參數:已排成遞增的n個無符號數仍存放在由BX指示首址的位元組緩存區中
; 所用寄存器:DI---用來存放n-1,即(SI)-1 , AX --- 用來存放臨時數
; 演算法:一次找一個最大的然後直接遞歸
SORT PROC
CMP SI , 1
JG EXECUTE ; 大於一個數就執行排序, 否則直接跳出子程序
RET
EXECUTE :
PUSH AX
PUSH DI
PUSH SI ; 保護現場
MOV DI , SI
LOPA :
DEC DI
CMP DI , 0
JNE COMPARE ; 不相等就繼續比較 ....
DEC SI ; 等於0 , 進行下一輪的調用
CALL SORT ;
POP SI
POP DI
POP AX
RET ; 返回
COMPARE :
MOV AL , [BX+DI-1] ; 第DI個數
CMP AL , [BX+SI-1] ; 第SI個數
JLE LOPA ; 小於不交換
XCHG AL , [BX+SI-1] ; 交換兩個數
MOV [BX+DI-1] , AL
JMP LOPA
SORT ENDP
CODE ENDS
END START

㈩ 一個關於C語言數組排序的問題

#include<stdio.h>
/**排序無用、邏輯錯明顯**/
void main()
#define n 5
{
int a[n],i,j,min;
printf("請輸入數組:");
for(i=0;i<n;i++)
scanf("%d",&a[i]);
//若使用宏n這里有可能會數組越界 根據編譯器類型。
for(i=0;i<sizeof(a)/sizeof(a[0])-1;i++)
{ //可以參考冒泡排序
min=a[i];
for(j=i+1;/*應該是j*/j<sizeof(a)/sizeof(a[0]);j++)//不是i 是j
{
if (min>a[j])
min=a[j];
}
a[i]=min;//這里會導致 a[i]=minvalue forever.
}
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
printf("%3d ",a[i]);
}

參照一個排序演算法來寫。網路c冒泡排序。

熱點內容
穿越火線掛機腳本 發布:2024-10-05 13:05:44 瀏覽:33
分解質因數c語言 發布:2024-10-05 12:15:53 瀏覽:777
mysql存儲過程字元編碼 發布:2024-10-05 12:05:48 瀏覽:182
c語言命名 發布:2024-10-05 11:56:38 瀏覽:617
編程哪個好學習 發布:2024-10-05 11:50:59 瀏覽:999
為什麼不買安卓旗艦 發布:2024-10-05 11:46:04 瀏覽:381
ostcb編譯條件 發布:2024-10-05 11:28:24 瀏覽:993
win10怎麼關閉登錄密碼 發布:2024-10-05 11:09:55 瀏覽:936
降溫解壓器 發布:2024-10-05 10:54:15 瀏覽:421
軋鋼壓縮空氣 發布:2024-10-05 10:54:10 瀏覽:185