快速排序, 传统递归实现, 非递归实现
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]
相关文章推荐