排序算法C语言实现——快速排序的递归和非递归实现
nlogn
*/
/*
原理:
快速排序(Quicksort)是对冒泡排序的一种改进。
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
*/
/*QuickSort_getKey:选取首元素、中间元素、尾元素这3个元素中间大小的元素,作为Key */
/*Key保存在数组首元素*/
void QuickSort_getKey(int *data, size_t len)
{
size_t iMin,iMid,iMax;
int iTmp=0;
if((NULL == data) || (len < 3))
{
return;
}
iMin=0,iMid=len/2,iMax=len-1;
if(data[iMin] > data[iMid])
{
iTmp=data[iMin];
data[iMin]=data[iMid];
data[iMid]=iTmp;
}
if(data[iMid] > data[iMax])
{
iTmp=data[iMid];
data[iMid]=data[iMax];
data[iMax]=iTmp;
}
/*至此iMax保存3者中最大的元素,我们要把中间大小的元素放在首元素位置*/
if(data[iMid] > data[iMin])
{
iTmp=data[iMin];
data[iMin]=data[iMid];
data[iMid]=iTmp;
}
}
{
size_t i=0,j=len-1;
int key=0;
if(NULL == data)
{
/*throw("Invalid Parameter");*/
return;
}
if(len<=1)
{
return;/*递归结束标志*/
}
/*选取Key,置于数组首元素位置*/
QuickSort_getKey(data, len);
key=data[i];
while(i<j)
{
while((key<=data[j]) && (i<j))
{
j--;
}
data[i]=data[j];
while((key>=data[i]) && (i<j))
{
i++;
}
data[j]=data[i];
}
data[i]=key;
QuickSort_recursion(data, i);
QuickSort_recursion(data+i+1, len-i-1);
}
nlogn
*/
typedef struct sortFlag
{
size_t start;
size_t len;
}stSortFlag;
{
size_t iCount;
stSortFlag* stSort;
}stStack;
{
size_t i=0,j=0,iStart=0,iLen=0;
int key=0;
if(NULL == data)
{
/*throw("Invalid Parameter");*/
return;
}
if (len < 2)
{
return;
}
stck.iCount = 0;
stck.stSort = NULL;
/*最坏情况需要len个栈空间*/
stck.stSort = (stSortFlag*)malloc(len * sizeof(stSortFlag));
if(NULL == stck.stSort)
{
return;
}
stck.stSort[stck.iCount].len=len;
++stck.iCount;
/*用栈代替递归
每次用递归的时候均入栈
每次运算的时候均出栈
栈为空则完成排序
*/
while(stck.iCount)
{
--stck.iCount;/*取一个元素进行排序,相当于出栈*/
iStart=stck.stSort[stck.iCount].start;
iLen=stck.stSort[stck.iCount].len;
i=iStart;
j=iStart+iLen-1;
/*选取Key,置于数组首元素位置*/
QuickSort_getKey(data+iStart, iLen);
key=data[i];
while(i<j)
{
while((key<=data[j]) && (i<j))
{
j--;
}
data[i]=data[j];
while((key>=data[i]) && (i<j))
{
i++;
}
data[j]=data[i];
}
data[i]=key;
if((i-iStart) > 1)
{
/*stck.stSort[stck.iCount].start=iStart;*/ /*值未变,此行语句可省略*/
stck.stSort[stck.iCount].len=i-iStart;
++stck.iCount;
}
if((iStart+iLen-1-i) > 1)
{
stck.stSort[stck.iCount].start=i+1;
stck.stSort[stck.iCount].len=iStart+iLen-i-1;
++stck.iCount;
}
}
if(NULL != stck.stSort)
{
free(stck.stSort);
}
}
排序算法C语言实现——快速排序的递归和非递归实现的更多相关文章
- C#实现(递归和非递归)高速排序和简单排序等一系列排序算法
本人由于近期工作用到了一些排序算法.就把几个简单的排序算法.想冒泡排序,选择排序,插入排序.奇偶排序和高速排序等整理了出来,代码用C#代码实现,而且通过了測试.希望能给大家提供參考. ...
- 扩展欧几里德算法(递归及非递归实现c++版)
今天终于弄懂了扩展欧几里德算法,有了自己的理解,觉得很神奇,就想着写一篇博客. 在介绍扩展欧几里德算法之前,我们先来回顾一下欧几里德算法. 欧几里德算法(辗转相除法): 辗转相除法求最大公约数,高中就 ...
- C语言实现 二分查找数组中的Key值(递归和非递归)
基本问题:使用二分查找的方式,对数组内的值进行匹配,如果成功,返回其下标,否则返回 -1.请使用递归和非递归两种方法说明. 非递归代码如下: #include <stdio.h> int ...
- 汉诺塔算法的递归与非递归的C以及C++源代码
汉诺塔(又称河内塔)问题其实是印度的一个古老的传说. 开天辟地的神勃拉玛(和中国的盘古差不多的神吧)在一个庙里留下了三根金刚石的棒,第一根上面套着64个圆的金片,最大的一个在底下,其余一个比一 个小, ...
- 回溯算法 DFS深度优先搜索 (递归与非递归实现)
回溯法是一种选优搜索法(试探法),被称为通用的解题方法,这种方法适用于解一些组合数相当大的问题.通过剪枝(约束+限界)可以大幅减少解决问题的计算量(搜索量). 基本思想 将n元问题P的状态空间E表示成 ...
- 汉诺塔算法c++源代码(递归与非递归)[转]
算法介绍: 其实算法非常简单,当盘子的个数为n时,移动的次数应等于2^n - 1(有兴趣的可以自己证明试试看).后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步操作就可以了.首先把三根柱 ...
- 求字符串长度之递归与非递归的C语言实现
在上一篇中介绍了字符串拷贝的递归与非递归的实现,这里就不在赘述递归原理. 递归求字符串长度_strlen: 1 int _strlen(const char *src) 2 { 3 if( src = ...
- AJPFX:递归与非递归之间的转化
在常规表达式求值中: 输入为四则运算表达式,仅由数字.+.-.*./ .(.) 组成,没有空格,要求求其值. 我们知道有运算等级,从左至右,括号里面的先运算,其次是* ./,再是+.- : 这样我们就 ...
- 二叉树之AVL树的平衡实现(递归与非递归)
这篇文章用来复习AVL的平衡操作,分别会介绍其旋转操作的递归与非递归实现,但是最终带有插入示例的版本会以递归呈现. 下面这张图绘制了需要旋转操作的8种情况.(我要给做这张图的兄弟一个赞)后面会给出这八 ...
随机推荐
- [软件工程基础]PhyLab 技术规格说明书
由于暂不对后端有所改变,因此该部分技术规格说明书复用 Default 的技术规格说明书. 由于现阶段对于 Laravel 框架不熟悉,以及对于是否使用已有的轮子或者造轮子实现预想的功能还不清晰,因此暂 ...
- [ZPG TEST 114] 括号匹配【树分治 点分治 括号序列】
1. 括号匹配 有一棵树,每个节点上都有一个括号(左括号或者右括号).有多少个有序点对(u, v)从u到v的路径上的节点构成的字符串是一个合法的括号匹配?(我们称这样的点对是合法的) 输 ...
- Jasper_crosstab_Parameter_Crosstab Header
corsstab: Q : how to show filed value at crosstab Header Part? A : via pass parameter in crosstab. i ...
- centOS+uwsgi+nginx 部署flask项目,问题记录
用flask做的项目想要部署到centOS系统上,填了一些坑,终于成功了,记录一下遇到的问题: 此次部署主要是按照这个博客进行的 https://www.cnblogs.com/Ray-liang/p ...
- C#中MessageBox用法大全(附效果图)<转>
我们在程序中经常会用到MessageBox. MessageBox.Show()共有21中重载方法.现将其常见用法总结如下: 1.MessageBox.Show("Hello~~~~&quo ...
- wordpress注册收不到邮件
解决发送问题后又遇到个蛋疼的问题,点击激活邮件地址提示您的密码重设链接无效,请在下方请求新链接发现原来是显的没事的wordpress在激活链接前后都加了<>,而邮箱把后面的>当成是链 ...
- 【Linux】Tmux分屏
1.Tmux Arch维基: https://wiki.archlinux.org/index.php/Tmux_(简体中文) 官方WIKI: https://github.com/tmux/tmux ...
- arcgis jsapi接口入门系列(7):鼠标在地图画线
初始化,每个map执行一次就行 drawPolylineInit: function () { //画几何对象初始化 //新建一个图形图层用于存放画图过程中的图形 let layer = new th ...
- webpack前端构建工具学习总结(四)之自动化生成项目中的html页面
接续上文:webpack前端构建工具学习总结(三)之webpack.config.js配置文件 插件的介绍文档:https://www.npmjs.com/package/html-webpack-p ...
- Fixed table
废话不多说,直接代码. <!DOCTYPE> <html> <head> <meta charset="utf-8"/> <s ...