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

论坛 期权论坛 脚本     
匿名技术用户   2020-12-27 17:57   90   0

//传统递归方法实现

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

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP