有的时候也是不知道是为什么,就像高中数学王老师说的那样,熟能生巧,不理解的要学会接受,慢慢就会理解了。大二的时候进行数据结构课程设计,我选做的一个是将快速排序的递归程序修改成非递归的形式,我记得我当时修改了好久好几,总是觉得这个非递归不能办到,但是当时根本没有想到用栈的思想,现在又重新学习数据结构,知道了递归与栈之间的关系。在剑指offer这本书中读到递归的本质就是栈结构,所以将递归函数拆成非递归的最好用栈作为保存;
递归的代码更为简洁,但是当函数调用的层级很深的时候,有可能导致函数调用栈溢出,显示用栈基于循环实现的代码鲁棒性要好一些。(摘自剑指offer)
在快速排序中,若枢轴记录是从low指针开始,那么在第一次的循环中,必须要从high指针开始,因为这样就不会丢失数据。
首先介绍快速排序的思想:
1、设置两个指针分别是low,high指针,枢轴的关键字pivotkey。关键字pivotkey设置为low位置的记录。首先从high所指向位置起向前搜索找到第一个比pivotkey小的记录,此时low位置上的关键字被替换为high位置上的记录,然后再从low 位置开始向前搜索,找到第一个比pivotkey大的记录,此时high位置上的记录被替换为low位置上的记录,直至low=high,第一趟结束,此时将分割成两个小序列。
然后在对这些小序列分别进行步骤1,直至所有的小序列进行了步骤1,结束。
从快速排序的思想来看很明显是用递归的函数进行。
递归思想的代码如下:
#include<iostream>
#include<stack>
using namespace std;
int partation(int *L,int low,int high)
{
int key=L[low];
while(low<high)
{
while(low<high&&L[high]>=key)
--high;
L[low]=L[high];
while(low<high&&L[low]<=key)
++low;
L[high]=L[low];
}
L[low]=key;
return low;
}
void Qsort(int *L,int low,int high)
{
if(low<high)
{
int pivotloc=partation(L,low,high);
Qsort(L,low,pivotloc-1);
Qsort(L,pivotloc+1,high);
}
}
nt main()
{
int L[8]={49,38,65,97,76,13,27,49};
Qsort(L,0,7);
cout<<"利用递归的方法"<<endl;
for(int i=0;i<8;i++)
cout<<L[i]<<" ";
cout<<endl;
return 0;
}
然后是将递归的改成非递归的,然后是自己的代码写的还是有点冗长。
要有用栈存放low,high指针,所以最好有个结构体这样不容易混乱,结构体如下:
struct strLocation{
int low;
int high;
};
#include<iostream>
#include<stack>
using namespace std;
struct strLocation{
int low;
int high;
};
void partation2(int *L,int low,int high,stack<strLocation>&s)
{
strLocation sLocL,sLocH;
sLocL.low=low;
sLocH.high=high;
int key=L[low];
while(low<high)
{
while(low<high&&L[high]>=key) --high;
L[low]=L[high];
while(low<high&&L[low]<=key)++low;
L[high]=L[low];
}
L[low]=key;
sLocH.low=low+1;
sLocL.high=low-1;
s.push(sLocL);
s.push(sLocH);
}
void Qsort2(int *L,stack<strLocation>&s)
{
while(!s.empty())
{
strLocation sLoc=s.top();
s.pop();
if(sLoc.low<sLoc.high)
partation2(L,sLoc.low,sLoc.high,s);
}
}
int main()
{
int L1[8]={49,38,65,97,76,13,27,49};
strLocation loc;
loc.low=0;
loc.high=7;
stack<strLocation>s;
s.push(loc);
Qsort2(L1,s);
cout<<"利用非递归的方法"<<endl;
for(int i=0;i<8;i++)
cout<<L1[i]<<" ";
cout<<endl;
return 0;
}