您的位置:首页 > 其它

快速排序, 传统递归实现, 非递归实现

2013-07-02 16:32 351 查看
//传统递归方法实现

void swap(int *a , int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}

//划分函数
int  partition(int *arr , int left, int right)
{
int key = arr[left];
while(left<right){
while(arr[left]< key && left<right){
left++;
}
swap(&arr[left] , &key);
while(arr[right]> key && left<right){
right--;
}
swap(&arr[right] , &key);
}
return left;
}
// 递归左右子序列。
void quickSort(int *arr , int left , int right)
{
if(left<right){
int mid = partition(arr , left , right);
quickSort(arr , left  , mid-1);
quickSort(arr , mid+1 , right);
}
}


/*
*   二叉树先根遍历 , 递归实现, 是不是和上面快速排序中的递归结构一样?
*/
void preOrder(BiTree T)
{
if(T!=NULL){

display(T->left);
printf(" %d",T->data);
display(T->right);
}
}

二叉树先根遍历,非递归实现。 使用一个栈消除 递归

void preOrder2(BiTree T)
{
printf("T->left->left->left=%p \n",T->left->left->left);
BiTree stack[100]={NULL};
int top = -1;
BiTree p  = T;
stack[++top] = p;
p=p->left;
/*
注意这的条件,栈不为空 或者 p不为空。遍历中右转操作时,p为空。完成根和根的左子树遍历后,栈为空,但p指向右子树。
故而是 “或” 的关系,许多教科书在这里出错
*/
while(top>-1 || p!=NULL){
if(p != NULL)
{
printf(" %d " , p->data);  //对节点操作函数, 这里直接输出, 在快排序中调用划分函数
stack[++top] = p;
//printf("push %d\n",p->data);
p = p->left; // 左下走到底
}
else{
p = stack[top--];
//printf("pop");

p = p->right;  //右转
}
}
}

通过模仿二叉树的非递归遍历,可以非常轻松的写出快速排序非递归算法

栈元素的结构(需要入栈并回溯的信息)

#include<stdio.h>
typedef struct {
int left;
int right;
}Node;

int arr[] = {1,5,3,7,4,9,0};

int part(int left ,int right)
{
int key = arr[left];
while(left<right)
{
while(left<right && arr[right]>key)
{
right--;
}
arr[left] = arr[right];
while(left<right && arr[left]<key)
{
left++;
}
arr[right] = arr[left];
}//end while
arr[left] = key;
return left;
}

void Sort2(int left ,int right)
{
if(left<right)
{
int mid  = part(left , right);
Sort2(left ,mid-1);
Sort2(mid+1,right);
}

}

void Sort()
{
Node stack[7];
int top = 0;
int mid;
Node node;  //当前指针
node.left = 0;
node.right = 6;

while(top>-1 || node.left<node.right){
if(node.left < node.right)
{
stack[top++] = node;
mid = part(node.left ,node.right);
node.right = mid-1;
}
else
{
node = stack[--top];
node.left = mid+1;
}
} //end while
}
int main()
{
int i;
for(i=0;i<7;i++)
{
printf(" %d " , arr[i]);
}

//Sort2(0 , 6);
Sort();

//  -------output the result of QuickSort
printf("\n\n==================\n\n");
for(i=0;i<7;i++)
{
printf(" %d " , arr[i]);
}

getchar();
return 0;
}

研究非递归快速排序的意义:
直观的学习 其空间复杂度为 log n 即辅助栈最大深度, 学习递归结构消解,掌握nlog n 时间复杂度内排序的根本原理

人工控制栈的增长。对大量数据排序,栈空间分配可以人工控制,而不是被动的依靠OS。

进一步尝试, 合并排序的非递归实现。即利用二叉树后根(后序)遍历非递归实现。

以上代码均在 gcc4.2 ub
[code]

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: