//传统递归方法实现
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