本节用非递归算法来实现快速排序算法,通常非递归算法用栈来实现,本节先介绍使用栈的非递归算法,然后介绍一个不使用栈的非递归算法。
1. 使用栈的非递归算法
使用栈的非递归算法编码如下。
/** 快速排序算法的使用栈的非递归算法函数
@param SORTTABLE *pTable——排序表指针
@param UINT uStart——表中要排序数据区间的起点,为数组下标
@param UINT uEnd——表中要排序数据区间的终点,为数组下标
@param COMPAREFUNC CompareFunc——数据比较函数
@return void——无
void SortTable_QuickSort2( SORTTABLE *pTable,UINT uStart,UINT uEnd,
COMPAREFUNC CompareFunc)
{
STACK *pStack;
UINT uLow;
UINT uHigh;
UINT uMid;
uLow = uStart;
uHigh = uEnd;
pStack = Stack_Create(uHigh - uEnd);
(void)Stack_Push(pStack,(void *)uLow);
(void)Stack_Push(pStack,(void *)uHigh);
while ( !Stack_IsEmpty(pStack) )
{
uHigh = (UINT)Stack_Pop(pStack);
uLow = (UINT)Stack_Pop(pStack);
if ( uLow < uHigh )
{
uMid = SortTable_Split(pTable,uLow,uHigh,CompareFunc );
if ( uMid > uLow )
{
(void)Stack_Push(pStack,(void *)uLow );
(void)Stack_Push(pStack,(void *)(uMid-1 ));
}
if ( uHigh > uMid )
{
(void)Stack_Push(pStack,(void *)(uMid + 1) );
(void)Stack_Push(pStack,(void *)uHigh);
}
}
Stack_Destroy(pStack,NULL);
}
}
在使用栈的非递归算法中,要频繁调用栈的操作函数,函数调用的开销是很大的,如果把栈操作改成不用栈函数调用,则效率会有所提高。
2. 不使用栈的非递归算法
不使用栈函数调用的非递归算法编码如下。
/** 排序表的快速排序函数,不使用栈调用的非递归算法,将指定区间的数据用快速排序算
法排好
@param SORTTABLE *pTable——排序表指针
@param UINT uStart——要排序的区间起点
@param UINT uEnd——要排序的区间终点
@param COMPAREFUNC CompareFunc——数据比较函数
@return void——无
*/
void SortTable_QuickSort( SORTTABLE *pTable,UINT uStart,UINT uEnd,
COMPAREFUNC CompareFunc)
{
UINT *puStack;
UINT uStackTop; 软件开发网 www.mscto.com
UINT uLow;
UINT uHigh;
UINT uMid;
if ( uEnd-uStart < 1 )
{
return;
}
uLow = uStart;
uHigh = uEnd;
puStack = (UINT *)malloc((uHigh-uLow + 1) *sizeof(UINT));
if ( puStack == NULL )
{
return CAPI_FAILED;
}
uStackTop = 0;
puStack[uStackTop] = uLow;
++uStackTop;
puStack[uStackTop] = uHigh;
++uStackTop;
while ( uStackTop != 0 )
{
--uStackTop;
uHigh = puStack[uStackTop];
--uStackTop;
uLow = puStack[uStackTop];
if ( uLow < uHigh )
{
uMid = SortTable_Split(pTable,uLow,uHigh,CompareFunc );
if ( uMid-uLow > uHigh-uMid )
{
puStack[uStackTop] = uLow;
++uStackTop;
puStack[uStackTop] = uMid-1;
++uStackTop;
if ( uHigh > uMid )
{
puStack[uStackTop] = uMid + 1;
++uStackTop;
puStack[uStackTop] = uHigh;
++uStackTop;
}
}
else
{
puStack[uStackTop] = uMid + 1;
++uStackTop;
puStack[uStackTop] = uHigh;
++uStackTop;
if ( uMid > uLow )
{
puStack[uStackTop] = uLow;
++uStackTop;
puStack[uStackTop] = uMid-1;
++uStackTop;
}
}
}
}
free( puStack );
}
至此,我们介绍了快速排序算法的三个不同版本:递归实现、使用栈的非递归实现、不使用栈的非递归实现。在这里需要讨论一下递归算法和非递归算法的效率问题。
=============================================================================
前段看到过一个问题(忘记在哪里了),用非递归的方式实现快速排序,今天又翻了出来,把代码贴上,给自己以后留个参考,代码中包括自己当时对程序改进的过程,请大家多提意见。
#include "stdafx.h"
#include <iostream>
#include <stack>
#define MAX_SIZE 10
using namespace std;
typedef int elem;
typedef std::stack<int> Stack;
int partition(elem *pData, int low, int high);
void swap(elem& a, elem& b);
void qsort(elem* pData, int low, int high);
void qsort2(elem* pData, int low, int high);
void qsort3(elem* pData, int low, int high);
int partition(elem *pData, int low, int high)
{
elem key = pData[low];
while(low < high)
{
while(low < high && pData[high] >= key)
high--;
swap(pData[low], pData[high]);
while(low < high && pData[low] <= key)
low++;
swap(pData[low], pData[high]);
}
return low;
}
void swap(elem& a, elem& b)
{
if(&a != &b)
{
a ^= b;
b ^= a;
a ^= b;
}
}
//这个是原始的算法
void qsort(elem* pData, int low, int high)
{
if(low < high)
{
int pivot = partition(pData, low, high);
qsort(pData, low, pivot - 1);
qsort(pData, pivot + 1, high);
}
}
//这个是第一次转化成递归以后的算法
void qsort2(elem* pData, int low, int high)
{
Stack st;
if(low < high)
{
int pivot = partition(pData, low, high);
st.push(low);
st.push(pivot - 1);
st.push(pivot + 1);
st.push(high);
while(!st.empty())
{
high = st.top();
st.pop();
low = st.top();
st.pop();
pivot = partition(pData, low, high);
if(low < high)
{
st.push(low);
st.push(pivot - 1);
st.push(pivot + 1);
st.push(high);
}
}
}
}
//这个是转化成递归以后改进的算法
void qsort3(elem* pData, int low, int high)
{
Stack st;
int tmp;
if(low < high)
{
int pivot = partition(pData, low, high);
st.push(low);
st.push(pivot - 1);
st.push(pivot + 1);
st.push(high);
while(!st.empty())
{
high = st.top();
st.pop();
low = st.top();
st.pop();
if(low < high)
{
pivot = partition(pData, low, high);
tmp = pivot - 1;
if(low < tmp)
{
st.push(low);
st.push(tmp);
}
tmp = pivot + 1;
if(tmp < high)
{
st.push(tmp);
st.push(high);
}
}
}
}
}
//测试代码
int _tmain(int argc, _TCHAR* argv[])
{
elem data[MAX_SIZE] = {12, 1, 13, 14, 67, 23, 12, 3, 90, 76};
//qsort(data, 0, MAX_SIZE - 1);
//qsort2(data, 0, MAX_SIZE - 1);
qsort3(data, 0, MAX_SIZE - 1);
for(int i=0; i< MAX_SIZE; i++)
{
cout << data[i] << " ";
}
cout << endl;
cin.get();
return 0;
}