高效排序——希爾排序


希爾排序是一種高性能的排序算法 ,其核心思想在於:

1.將數組分割為若干子數組,對每個子數組進行簡單算法排序(如插入,梳排序均可);

2.將排序后的子序列合並,繼續重復步驟1;

直到所分的數組為1組。,算法結束。

       那么上述中,如何分組呢?分組方式見《C++數據結構與算法》393頁最下面的划分方式,當然對於希爾排序而言,目前並沒有一種理論上最優的划分方式,書上提供的是一種較為優秀的划分方式。

下面直接上代碼:

  1 # include"iostream"
  2 # include "vector"
  3 # include "ctime"
  4 # include "cstdlib"  // 如果我們想通過隨機數來驗證我們的想法。應該預先給vecot分配內存
  5 # include "cmath"
  6 
  7 using namespace std;
  8 void insert_sort(vector<int> & );
  9 void ChooseSort(vector<int> &);
 10 void BubbleSort(vector<int> &);
 11 void CombSort(vector<int> & );
 12 void ShellSort(vector<int> &);
 13 int main()
 14 {
 15     const int MAX_NUMBER = 10000;//生成的隨機數的個數
 16     const int MIN_VALUE = 1;   //隨機數值的下界
 17     const int MAX_VALUE = 30000;//隨機數值的上界
 18     vector<int> a;
 19     a.reserve(MAX_NUMBER);//預先分配內存你,預防迭代器的失效。否則內存搬移,迭代器容易失效
 20 
 21     // 采用控制台輸入的方式 
 22     //int temp;
 23     //while (cin >> temp)
 24     //{
 25     //    a.push_back(temp);
 26     //    if (cin.get() == '\n') //注意這種用法,用的很多。
 27     //    {
 28     //        break;
 29     //    }
 30     //}
 31 
 32     //采用隨機數生成法。
 33     srand((unsigned)time(NULL));//根據時鍾生成不同的種子,保證每次運行程序產生不同的隨機數
 34     for (int i = 1; i <= MAX_NUMBER; i++)
 35     {
 36         int temp;
 37         temp = (rand() % (MAX_VALUE - MIN_VALUE + 1)) + MIN_VALUE;//生成[MIN_VALUE,MAX_VALUE]之間的整數隨機數
 38         a.push_back(temp);
 39     }
 40     //cout << "The initial order: ";    數據量太大,不適合輸出
 41     //vector<int>::iterator ia = a.begin();
 42     //for (; ia != a.end(); ia++)
 43     //{
 44     //    cout << *ia << " ";
 45     //}
 46     //cout << endl;
 47     vector<int> b(a);
 48     vector<int> c(a);
 49     vector<int> d(a);
 50     vector<int> e(a);
 51     //show the initial order of the vector
 52     //cout << "The initial order before Sorting : ";
 53     //vector<int> ::iterator ia = a.begin();
 54     //for (; ia != a.end(); ia++)
 55     //{
 56     //cout << *ia << " ";
 57     //}
 58     //cout << endl;
 59     // 插入排序測試
 60     clock_t start, finish;
 61     double runtime;
 62     start = clock();
 63     insert_sort(a);
 64     finish = clock();
 65     runtime = (double)(finish - start) / CLOCKS_PER_SEC;
 66     cout << "The time of Insert Sort algorithm is:" << runtime << "s" << endl;
 67     // 選擇排序測試
 68     start = clock();
 69     ChooseSort(b);
 70     finish = clock();
 71     runtime = (double)(finish - start) / CLOCKS_PER_SEC;
 72     cout << "The time of Choose Sort algorithm is:" << runtime << "s" << endl;
 73     // 冒泡排序測試
 74     start = clock();
 75     BubbleSort(c);
 76     finish = clock();
 77     runtime = (double)(finish - start) / CLOCKS_PER_SEC;
 78     cout << "The time of Bubble Sort algorithm is:" << runtime << "s" << endl;
 79     // 梳排序測試
 80     start = clock();
 81     CombSort(d);
 82     finish = clock();
 83     runtime = (double)(finish - start) / CLOCKS_PER_SEC;
 84     cout << "The time of Comb Sort algorithm is:" << runtime << "s" << endl;
 85     //希爾排序
 86     start = clock();
 87     ShellSort(e);
 88     finish = clock();
 89     runtime = (double)(finish - start) / CLOCKS_PER_SEC;
 90     cout << "The time of Shell Sort algorithm is:" << runtime << "s" << endl;
 91     system("pause");
 92     return 0;
 93 }
 94 //插入排序
 95 void insert_sort(vector<int> & sort_a)  ///注意,采用vector<int> 是可以作為參數進行傳遞的,那么是否可以作為返回類型使用呢?
 96 {
 97     int a_size ,temp;
 98     a_size = sort_a.size();
 99     for (int i = 1,j; i < a_size; i++)//注意,將j放在這里聲明,不要放在下一個循環中聲明,否則會造成多次聲明?(但是作用域沒變,多次聲明應該被禁止,所以沒有多次聲明?)
100     {
101         temp = sort_a[i];
102         for (j = i; (j > 0) && (sort_a[j - 1] > temp); j--)//這里先后順序的差別,導致了數組的越界,
103         {   
104             sort_a[j] = sort_a[j-1];
105         }
106         sort_a[j] = temp;
107     }
108     //return sort_a;//說明可以將vector<int> 本身作為函數的返回值使用,但是需要清楚的是:返回的時候,內存實際上發生了局部變量復制,所以是否考慮返回引用???
109 }
110 //選擇排序
111 void ChooseSort(vector<int> & sort_a)
112 {
113     int a_size,MinNum;
114     a_size = sort_a.size();
115     for (int i = 0, j; i < a_size; i++)
116     {
117         int Loc = i;
118         MinNum = sort_a[i];//本質是隨機迭代器的使用
119         //temp = sort_a[i];
120         for (j = i+1; j < a_size; j++)
121         { 
122             if (sort_a[j] < MinNum)
123             {
124                 MinNum = sort_a[j];
125                 Loc = j;
126             }
127         }
128         //sort_a[i] = MinNum;//用於交換,但是本身自帶的函數可以實現
129         //sort_a[Loc] = temp;
130         if (i != Loc)
131         {
132             swap(sort_a[i], sort_a[Loc]);//vector自帶的東西
133         }
134     }
135 }
136 //冒泡排序
137 void BubbleSort(vector<int> & sort_a)
138 {
139     int a_size;
140     a_size = sort_a.size();
141     for (int j = 0; j < a_size-1; j++)
142     {
143         for (int i = 0; i < a_size - 1-j; i++)
144         {
145             if (sort_a[i]>sort_a[i + 1])
146                  swap(sort_a[i], sort_a[i + 1]);
147         }
148     }
149 }
150 //梳排序
151 void CombSort(vector<int> & sort_a)
152 {
153     int step,j,k;
154     step = sort_a.size();
155     while ((step = int(step / 1.3)) >0)
156     {
157         for (j = sort_a.size() - 1; j >= step; j--)
158         {
159             k = j - step;
160             if (sort_a[j] < sort_a[k])
161             {
162                 swap(sort_a[j], sort_a[k]);
163             }
164         }
165     }
166 }
167 
168 //希爾排序
169 void ShellSort(vector<int> & sort_a)
170 {
171     int a_size;
172     a_size = sort_a.size();//得到數組大小
173     vector<int> ht;
174     ht.resize(floor(log(a_size)/log(3)));//為增量數組預先分配空間
175     ht[0] =1;//為何這樣會出錯???預分配空間后為何不能使用隨機訪問的機制???
176     for (int i = 1; i<=ht.size()-1; i++)
177     {
178         ht[i] = 3 * ht[i - 1] + 1;
179     }
180     int ht_size = ht.size();
181     vector<int> new_a;
182     new_a.resize(a_size);
183     for (int count = ht.size(), temp; count >= 1; count--)
184     {
185         temp = ht[count - 1];//temp的值決定了當前會被分成多少組
186         //vector<int>a_divide;
187         vector<vector<int>> aMatrix(temp, vector<int>(ceil(a_size / (1.0*temp))));//定義一個二維數組,
188         for ( int i = 0; i < temp; i++)
189         {
190             int j;
191             for (j = 0; (i + j*temp) < a_size; j++)
192             {
193                 aMatrix[i][j] = sort_a[i + j*temp];//將應該分為同一組的數據挑選出來    
195             }
196             if (ceil(a_size / (1.0*temp))>j)
197             {
198                 aMatrix[i][j] = 33333;//用於解決有0的問題
199             }
200            ;//問題是,本身有些空間存在0,這樣寫,將本身沒有的0元素也進行了排序
201         }
202         //截止到這里,程序是沒有問題的,也就是大部分是正確的,但是下面存在的問題是:數組中的0怎么辦
203         for(int k = 0, q = 0; k < ceil(a_size / (1.0*temp)); k++)
204         {
205             for (int p = 0; p < temp; p++)
206             {
207                 sort_a[q] = aMatrix[p][k];
208                 q = q + 1;
209                 if (q >= a_size)
210                     break;
211             }
212             if (q >= a_size)
213                 break;
214         }
215     }
216         
217 }

實際上,上述給出很多排序算法的代碼。

169-215行為希爾排序算法的實現,對算法的各個部分進行解讀:

179行以前,求解每次分組的次數;

200行以前,將同一組的數據提取出來,組成一個矩陣,每行表示同一組的,不同行表示不同分組,對每行的數據采取梳排序

200行以后,將輸入向量更新為矩陣列向量的拼接值

重復迭代,直到h =1;

針對希爾排序,其主要思想是一種分治的思想,給出上述排序算法效率的對比:

該次測試中,隨機數的個數為10000個,從結果中可以看出,希爾排序效率最高,但其和梳排序的效率較為接近(思考原因)

在手擼希爾排序算法的過程中,遇到了很多c++中的問題,在此給出以下說明:

ht.resize(floor(log(a_size)/log(3)));這句代碼的本意是給數組ht預分配空間,開始使用的是ht.reserve(),但發現這樣寫,在調試的時候,導致ht[0] =1;出錯,這說明並沒有達到我們想要的結果。百度了下,發現:

可見,使用reserve()並不會改變vector的大小,並不會和我們想的那樣在內存中開辟出一片空間給vector。因此,若我們需要開辟一塊可用空間,應該用resize()。那reserve()的作用是什么呢?(懸而未決)

vector<vector<int>> aMatrix(temp, vector<int>(ceil(a_size / (1.0*temp))));定義了一個temp×ceil(a_size / (1.0*temp))大小的二維數組aMatrix,注意這是使用vector定義的二維數組,需要注意的是vector允許這種嵌套定義。

另一個點在於CombSort(aMatrix[i]),CombSort的形參形式為數組引用,但這里傳遞是一個1維指針,說明某種意義上兩者可以相互轉換。但這個本質上說明了一個二維數組,只取一維其實就是一個指針。

 
        

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM