几种常见的排序算法

冒泡排序

冒泡排序算法的运作如下:

1、比较相邻的元素。如果第一个比第二个大,就交换他们两个。

2、对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

3、针对所有的元素重复以上的步骤,除了最后一个。

4、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

void BubbleSort(int arr[], int n)
{int i = 0, j =0;    for(i = 0; i < n; i++)for(j = 0; j < n - 1 - i; j++){if(arr[j] > arr[j + 1]){arr[j] = arr[j] ^ arr[j+1];arr[j+1] = arr[j] ^ arr[j+1];arr[j] = arr[j] ^ arr[j+1];}            }    
}

交换两个数据,可以用用临时变量,也可用以下的两个方法
a = a^b;
b = a^b;
a = a^b;
或者
a = a + b;
b = a - b;
a = a - b;

冒泡排序变异版-鸡尾酒排序法

/*** 鸡尾酒排序法* *正常冒泡排序法,每次遍历都是向一个方向冒出最值,*而鸡尾酒排序法是变异的冒泡排序法,往返方向找出最值*/
public void sort(int[] a) {//需要来回a,length/2趟for (int i = 0; i < a.length / 2; i++) {//类冒泡,交换最大值至右端for (int j = i; 1 + j < a.length - i; j++)if (a[j] > a[1 + j])Arr.swap(a, j, 1 + j);//类冒泡,交换最小值至左端for (int j = a.length - i - 1; j > i; j--)if (a[j - 1] > a[j])Arr.swap(a, j - 1, j);}
}

冒泡排序改进版

/***改进的冒泡算法,在第i次遍历时,若没有交换数据,说明剩余的数据已经是有序的*/
void BubbleSort(int arr[]) {boolean didSwap;for(int i = 0, len = arr.length; i < len - 1; i++) {didSwap = false;for(int j = 0; j < len - i - 1; j++) {if(arr[j + 1] < arr[j]) {swap(arr, j, j + 1);didSwap = true;}}if(didSwap == false)return;}    
}


选择排序

选择排序的工作原理:

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

/*** @brief 选择排序** @param list[] 要排序的数组* @param n 数组中的元素数量*/
void SelectSort(int *list, int list_size)
{int i, j; // 用于循环int min_index; // 当前最小值的 indexint temp; // 用于交换// 最后一个元素不用排了, 所以可以 len - 1; 少一次循环for (i = 0; i < list_size - 1; ++i){// 假定当前的元素就是最小的min_index = i;// 查找剩下的元素当中最小的for (j = i; j < list_size; ++j){if (list[j] < list[min_index]){min_index = j;}}// 如果找到了比当前小的, 就把当前元素与之交换if (min_index != i){temp = list[i];list[i] = list[min_index];list[min_index] = temp;}}
}

归并排序

归并操作的过程如下:
1、申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
2、设定两个指针,最初位置分别为两个已经排序序列的起始位置
3、比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
4、重复步骤3直到某一指针到达序列尾
5、将另一序列剩下的所有元素直接复制到合并序列尾

/*** @brief 归并排序** @param *list 要排序的数组* @param n 数组中的元素数量*/
void MergeSort(int *list, int list_size)
{if (list_size > 1){// 把数组平均分成两个部分int *list1 = list;int list1_size = list_size / 2;int *list2 = list + list_size / 2;int list2_size = list_size - list1_size;// 分别归并排序merge_sort(list1, list1_size);merge_sort(list2, list2_size);// 归并merge_array(list1, list1_size, list2, list2_size);}
}/*** @brief 归并两个有序数组** @param list1* @param list1_size* @param list2* @param list2_size*/
void merge_array(int *list1, int list1_size, int *list2, int list2_size)
{int i, j, k;i = j = k = 0;// 声明临时数组用于存储归并结果int *list = malloc((list1_size + list2_size)*sizeof(int));// note: 只要有一个数组到达了尾部就要跳出// 也就是说只有两个都没有到达尾部的时候才执行这个循环while (i < list1_size && j < list2_size){// 把较小的那个数据放到结果数组里, 同时移动指针list[k++] = list1[i] < list2[j] ? list1[i++] : list2[j++];}// 如果 list1 还有元素,把剩下的数据直接放到结果数组while (i < list1_size){list[k++] = list1[i++];}// 如果 list2 还有元素,把剩下的数据直接放到结果数组while (j < list2_size){list[k++] = list2[j++];}// 把结果数组 copy 到 list1 里for (int ii = 0; ii < (list1_size + list2_size); ++ii){list1[ii] = list[ii];}free(list); 
}

快速排序

快速排序的步骤
1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。

/** * @brief 快速排序* * @param list  要排序的数组* @param lIndex 左下标* @param rIndex 右下标*/  
void QuickSort(int list[], int lIndex, int rIndex)
{if (lIndex < rIndex){int i = lIndex, j = rIndex, x = list[lIndex];//第一个元素作为基准数while (i < j){while(i < j && list[j] >= x) // 从右向左找第一个小于x的数j--; if(i < j)list[i++] = list[j];while(i < j && list[i] < x) // 从左向右找第一个大于等于x的数i++; if(i < j)list[j--] = list[i];}list[i] = x;QuickSort(list, lIndex, i - 1); // 递归调用QuickSort(list, i + 1, rIndex);}
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508708.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux下调试工具的应用

http://www.ibm.com/developerworks/cn/linux/l-pow-debug/

数据结构--赫夫曼树及其应用

讲解请参考 赫夫曼 ------ 赫夫曼树和赫夫曼编码的存储表示------ typedef struct {unsigned int weight;unsigned int parent,lchild,rchild; }HTNode,*HuffmanTree; typedef char ** HuffmanCode;void HuffmanCoding(HuffmanTree& HT,HuffmanCode & HC,int *w,int …

sqlite C/C++ API

官网&#xff1a;https://sqlite.org/download.html 下载代码安装三步走&#xff1a; ./configure // ./configure --help查看安装参数设置&#xff0c;学习configure的配置&#xff0c;明白安装后include、lib、bin等文件的位置 make make install学习SQL基本语法&#xff0…

线程属性总结

今天面试那哥们问起线程属性&#xff0c;me竟然就说出了一个&#xff0c;囧 学习&#xff1a;http://blog.csdn.net/zsf8701/article/details/7842392 http://blog.csdn.net/jxhnuaa/article/details/3254299 http://blog.sina.com.cn/s/blog_9bd573450101hgdr.html int pthre…

单链表面试经典问题

/************************************************** http://www.cnblogs.com/lifuqing/archive/2011/08/20/List.html http://www.cnblogs.com/wenjiang/p/3310233.html 链表经典问题汇总:http://blog.csdn.net/vividonly/article/details/6673758 链表有关的常见面试题:htt…

Linux SO_KEEPALIVE属性,心跳

对于面向连接的TCP socket,在实际应用中通常都要检测对端是否处于连接中,连接端口分两种情况: 1、连接正常关闭,调用close() shutdown()连接优雅关闭,send与recv立马返回错误,select返回SOCK_ERR; 2、连接的对端异常关闭,比如网络断掉,突然断电. 对于第二种情况,判断连接是否断…

Linux下ARM开发环境搭建

本人的系统环境&#xff1a;Linux ubuntu 3.8.0-35-generic #50-Ubuntu SMP Tue Dec 3 01:25:33 UTC 2013 i686 i686 i686 GNU/Linux 1、安装skyeye sudo apt-get install skyeye s kyeye -h可以看到skyeye的版本号为1.2.5也可以到http://sourceforge.jp/projects/sfnet_skyeye…

cygwin开发环境搭建与apt-cyg的应用

1、Cygwin安装 http://www.cygwin.com/下载安装工具 具体安装过程参照http://jingyan.baidu.com/article/6b97984d83dfe51ca2b0bf0e.html 2、Cygwin一些设置 打开Cygwin终端,右击打开 Options...选项 Text可以设置字体的一些属性,如大小、编码,Locale 选择C, Character set 选择…

CentOS下升级python版本

源码安装python 安装python源码所依赖的工具及依赖的库 yum install -y make gcc gcc-c yum install -y bzip2 bzip2-devel yum install zlib-devel openssl openssl-devel -y yum install -y make xz下载安装python源码 从官方网站或者华为镜像源下载所有需的源码包&#xff0…

linux下confstr与uname函数_获取C库与内核信息

#include <stdio.h> #include <sys/utsname.h> //unameint main(int argc, char **argv[]) {struct utsname u;if (uname(&u) ! -1) {printf("获取当前内核的名称和信息如下\n""sysname:%s\n""nodename:%s\n""release:%s\…

linux下getrlimit与sysconf函数

#include <stdio.h> #include <sys/time.h> #include <sys/resource.h>int main(int argc, char *argv[]) {struct rlimit nofile_rlmt;if (getrlimit(RLIMIT_NOFILE, &nofile_rlmt) ! -1) {printf("获取进程最大能打开的文件描述符个数信息:\n&quo…

Linux下environ环境变量操作函数

#include <stdio.h>int main(int argc,char *argv[],char **envptr) {int i0;for(i0; envptr[i]!NULL; i)printf("%s\n",envptr[i]);return 0; } main函数是程序的入口函数,int main(int argc,char *argv[]); argc是程序参数的个数,argv保存参数 与下边的程…

Linux网络编程--聊天室客户端程序

聊天室客户端程序 #define _GNU_SOURCE 1 #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> #include <stdio.h> #include <unistd.h> #include <string.h&…

二叉树学习之二叉查找树

写在前面的话 最近接到几个大学同学研究生毕业不是签华为就是签百度,本人取经得到:操作系统、数据结构与算法、网络编程与数据库是面试中利器。想想自己工作2.5年月薪还不到10K,过着苦逼的码农生活,而他们一出校门就是大放光芒(最起码进入的公司就让人觉得牛逼哄哄的).本人痛定…

二叉树学习之非递归遍历

二叉树递归遍历可谓是学过数据结构的同仁都能想一下就能写出来,但在应聘过程我们常常遇到的是写出一个二叉树非递归遍历函数,接着上篇文章写二叉树的非递归遍历,先难后易,一步一步的来. 先上代码: #include "binarytree.h" #include <stack> #include <queu…

二叉树学习之堆排序

认识堆是从堆排序开始的 二叉堆是完全二叉树或者是近似完全二叉树,堆存储在数组中: 根结点下标为0时,下标为n的元素的子结点下标分别为2*n1,2*n2,其父结点下标为(n-1)/2 二叉堆的特性: 1、父结点的键值总是>(<)任何一个子结点的键值 2、每个结点的左右子树都是二叉堆…

步入github世界

在源码的世界里&#xff0c;越来越多的优秀源码涌现&#xff0c;开源的世界不但代表他的优秀&#xff0c;也代表了他优秀的传播途径。 https://github.com/ github自从2008年现世&#xff0c;可谓是后来者居上。开源代码的公开库&#xff0c;优秀程序员的博客园&#xff0c;热心…

libevent学习__学习历程总结

The libevent API provides a mechanism to execute a callback function when a specific event occurs on a file descriptor or after a timeout has been reached. Furthermore, libevent also support callbacks due to signals or regular timeouts.环境搭建 下载: http:…

redis☞ python客户端

安装 https://pypi.python.org/pypi/redis/ https://github.com/andymccurdy/redis-py 参照官网,安装命令 sudo pip install redis 或者 sudo easy_install redis 亦或 源码包执行sudo python setup.py install实例 >>> import redis >>> r redis.Redis(ho…

Catalan数应用

Catalan数应用 Catalan数应用原理卡特兰数经典应用括号化买票找零组合数与阶乘计算 卡特兰数又称卡塔兰数&#xff0c;是组合数学中一个常出现在各种计数问题中的数列。由以比利时的数学家欧仁查理卡塔兰 (1814–1894)命名。 其前几项为 : 1, 2, 5, 14, 42, 132, 429, 1430,…