#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
using namespace std;
#define MAXSIZE 20
typedef int KeyType;
typedef struct{
KeyType key;
string otherinfo;
}RedType;
typedef struct{
RedType r[MAXSIZE+1];
int length;
void print();
}SqList;
typedef SqList HeapType;/*堆採用順序表存儲表示*/
void SqList::print()
{
for(int i=1;i<=length;i++)
cout<<r[i].key<<'\t'<<r[i].otherinfo<<endl;
}
/*直接插入排序*/
/*其時間複雜度爲O(n**2)*/
void InsertSort(SqList &L)
{
for(int i=2;i<=L.length;i++)/*length-1次迭代*/
if(L.r[i].key<L.r[i-1].key)/*從最後一個先左比較,若大,則保持位置不變*/
{
L.r[0]=L.r[i];/*r[0]作爲哨兵*/
L.r[i]=L.r[i-1];
for(int j=i-2;L.r[j].key>L.r[0].key;j--)/*找到比哨兵值小的位置,其前的元素後移*/
L.r[j+1]=L.r[j];
L.r[j+1]=L.r[0];/*插入正確的位置*/
}
}
/*其它插入排序*/
/*折半插入排序*/
/*利用折半查找來實現查找操作*/
/*時間複雜度還是O(n**2)*/
/*雖然查找省了時間,但仍然需要移位*/
void BInsertSort(SqList &L)
{
for(int i=2;i<=L.length;i++)
if(L.r[i].key<L.r[i-1].key)
{
L.r[0]=L.r[i];/*與直接插入排序的區別在於查找位置*/
int low=1,high=i-1,m;
while(low<=high)
{
m=(low+high)/2;//折半
if(L.r[m].key>L.r[0].key)//插入點在低半區
high=m-1;
else//插入點在高半區
low=m+1;
}
for(int j=i-1;j>=high+1;j--)//記錄後移
L.r[j+1]=L.r[j];
L.r[high+1]=L.r[0];//插入
}
}
void ShellInsert(SqList &L,int dk)
{
for(int i=dk+1;i!=L.length;i++)
if(L.r[i].key<L.r[i-dk].key)/*需將L.r[i]插入有序增量子序列中*/
{
L.r[0]=L.r[i];/*暫存在L.r[0]中*/
for(int j=i-dk;j>0 && L.r[j].key>L.r[0].key;j-=dk)
L.r[j+dk]=L.r[j];/*記錄後移,查找插入位置*/
L.r[j+dk]=L.r[0];/*插入*/
}
}
/*希爾排序,又稱縮小增量排序,插入排序的一種*/
/*先將整個待排記錄序列分割成如干子序列進行直接插入排序,
待整個序列基本有序的時候,再對全體記錄進行一次直接插入排序*/
void ShellSort(SqList &L,int dlta[],int t)
{
for(int k=0;k<t;k++)
ShellInsert(L,dlta[k]);
}
/*快速排序*/
/*基本思想:通過一趟排序將代排記錄分割成獨立的兩部分,
其中一部分記錄關鍵字均比另一部分記錄的關鍵字小,
則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序*/
/*
快速排序是O(nlogn)的排序方法中,其平均性能最好。但初始記錄順序有序時,快排將退化爲氣泡排序
其時間複雜度變成O(n**2)
但快速排序需要一個棧空間來實習遞歸,若每一趟排序都將記錄序列均勻的分割成長度相近的
兩個子序列,則棧的最大深度爲[log2n+1];
最壞的時候,若每趟排序均偏向子序列的一端,則爲最壞情況,棧的最大深度爲n
*/
int Partition(SqList &L,int low,int high)
{
L.r[0]=L.r[low];/*用子表的第一個記錄作扭軸記錄*/
int pivotkey=L.r[low].key;/*扭軸記錄關鍵字*/
while(low<high)/*從表的兩端交替向中間掃描*/
{
while(low<high && L.r[high].key>=pivotkey) --high;
L.r[low]=L.r[high];/*將比扭軸記錄小的記錄移到低端*/
while(low<high && L.r[low].key<=pivotkey) ++low;
L.r[high]=L.r[low];/*將比扭軸記錄大的記錄移到高端*/
}
L.r[low]=L.r[0];/*扭軸記錄到位*/
return low;
}
/*遞歸形式的快速排序*/
void QSort(SqList &L,int low,int high)
{
if(low<high)/*長度大於1*/
{
int pivocloc=Partition(L,low,high);/*一分爲二*/
QSort(L,low,pivocloc-1);/*對低子表遞歸排序*/
QSort(L,pivocloc+1,high);/*對高子表遞歸排序*/
}
}
void QuickSort(SqList &L)
{
QSort(L,1,L.length);
}
/*簡單選擇排序*/
/*通過n-i次關鍵字的比較,從n-i+1個記錄中選出關鍵字最小的記錄,並和第i個記錄交換*/
/*簡單選擇排序,所需記錄移動的操作次數較少,其最小值爲“0”,最大值爲3(n-1)*/
/*比較次數相同,均爲n(n-1)/2。總的時間複雜度爲O(n**2)*/
int SelectMinKey(SqList &L,int i)
{
int imin=i;
for(int j=i+1;j!=L.length;j++)
{
if(L.r[j].key<L.r[imin].key)
{
imin=j;
}
}
return imin;
}
void SelectSort(SqList &L)
{
for(int i=1;i!=L.length;i++)
{
int j=SelectMinKey(L,i);
if(i!=j)
{
RedType temp;
temp=L.r[i];
L.r[i]=L.r[j];
L.r[j]=temp;
}
}
}
/*堆排序*/
/*只需要一個記錄大小的輔助空間,每個待排序的記錄僅佔一個存儲空間*/
/*由於堆排序最壞情況下,其時間複雜度也爲O(nlogn)。相對於快速排序,這是堆排序最大優點*/
/*堆排序僅需要一個記錄大小供交換用的輔助空間*/
void HeapAdjust(HeapType &H,int s,int m)
{
RedType rc=H.r[s];
for(int j=2*s;j<=m;j=j*2)/*沿key較大的孩子結點向下篩選*/
{
if(j<m && (H.r[j].key<H.r[j+1].key)) ++j;//j爲key較大的記錄的下標
if(!(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)
{
for(int i=H.length/2;i>0;--i)
HeapAdjust(H,i,H.length);/*建成大頂堆*/
for(i=H.length;i>1;--i)
{
RedType temp;/*將堆頂記錄和當前未經排序子序列中最後一個記錄相互交換*/
temp=H.r[i];
H.r[i]=H.r[1];
H.r[1]=temp;
HeapAdjust(H,1,i-1);/*將H.r[1..i-1]調整爲大頂堆*/
}
}
int main()
{
ifstream infile;
infile.open("data.txt");
if(!infile)
{
cerr<<"error:unable to open input file:"<<infile<<endl;
return -1;
}
string line;
SqList L;
L.length=0;
while(getline(infile,line))/*讀一行數據到line*/
{
L.length++;
istringstream stream(line);/*讀string功能*/
stream>>L.r[L.length].key>>L.r[L.length].otherinfo;
}
//InsertSort(L);
//BInsertSort(L);
//int dlta[3]={5,3,1};
//ShellSort(L,dlta,3);
//QuickSort(L);
//SelectSort(L);
HeapSort(L);
L.print();
return 0;
}
數據文件 data.txt
49 zhoujielun
38 xiaoshengyang
65 zhouxinchi
97 caiyilin
76 tangwei
13 liangcaowei
27 wujinru
49 yaoming