咱們知道快遞排序大部分的版本都是遞歸的方式來實現的:經過Pritation來實現劃分,並遞歸實現先後的劃分。因爲同窗上次百度二面面試官問起快速排序的非遞歸的實現方式,當時同窗不會,由於咱們大部分看到的都是遞歸方式來實現快速排序。並無關注非遞歸的方式。可是仔細想一想也是能夠作的,由於遞歸的本質是棧,所以咱們非遞歸實現的過程當中,藉助棧來保存中間變量就能夠實現非遞歸了。在這裏中間變量也就是經過Pritation函數劃分以後分紅左右兩部分的首尾指針,只須要保存這兩部分的首尾指針便可。面試
遞歸的方式顯現以下:函數
首先貼出Pritation函數的實現,由於遞歸和非遞歸都須要用到該函數,該函數實現的版本有多種,這裏採用我比較熟悉的。ui
1 int Pritation(int* a, int left, int right) 2 { 3 if (a == NULL || left < 0 || right <= 0||left>=right) 4 return -1; 5 int priot = a[left]; 6 int i = left, j = right; 7 while (i < j) 8 { 9 while (i > j&&a[j] >= priot) 10 j--; 11 if(i<j) 12 a[i]=a[j]; 13 while (i < j&&a[i] <= priot) 14 i++; 15 if(i<j) 16 a[j]=a[i]; 17 } 18 a[i] = priot; 19 return i; 20 }
而後貼出遞歸的代碼:(代碼簡潔明瞭)spa
1 void QuickSort(int *a, int left,int right) 2 { 3 if (a == NULL || left < 0 || right <= 0 || left>right) 4 return; 5 int k = Pritation(a, i, j); 6 //下面是遞歸實現的代碼 7 if (k > left) 8 QuickSort(a, left, k - 1); 9 if (k < right) 10 QuickSort(a, k + 1, right); 11 }
最後貼出非遞歸的實現方式:指針
1 void QuickSort(int *a, int left,int right) 2 { 3 if (a == NULL || left < 0 || right <= 0 || left>right) 4 return; 5 stack<int>temp; 6 int i, j; 7 //(注意保存順序)先將初始狀態的左右指針壓棧 8 temp.push(right);//先存右指針 9 temp.push(left);//再存左指針 10 while (!temp.empty()) 11 { 12 i = temp.top();//先彈出左指針 13 temp.pop(); 14 j = temp.top();//再彈出右指針 15 temp.pop(); 16 if (i < j) 17 { 18 int k = Pritation(a, i, j); 19 if (k > i) 20 { 21 temp.push(k - 1);//保存中間變量 22 temp.push(i); //保存中間變量 23 } 24 if (j > k) 25 { 26 temp.push(j); 27 temp.push(k + 1); 28 } 29 } 30 31 } 32 33 }
從上面的代碼能夠看出,保存中間變量的時候須要注意保存的順序,由於棧是後進先出的方式。code