咱们知道快递排序大部分的版本都是递归的方式来实现的:经过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