标签:排序
针对现实中的排序问题,算法有七把利剑可以助你马道成功。
首先排序分为四种:
交换排序: 包括冒泡排序,快速排序。
选择排序: 包括直接选择排序,堆排序。
插入排序: 包括直接插入排序,希尔排序。
合并排序: 合并排序。
冒泡排序简单来说就是利用两个for循环来进行排序,由前一个数据和后一个数据比较,如果前一个大于后一个则交换,这样如果从头循环一次,就会找到整个列表中最大的那个数,将其固定在最后一位,所以循环n次就能确定所有顺序了。
#include <stdio.h>
void swap(int *a, int *b); //交换两个数
int main()
{
int str[10];
int i, j;
//初始化数组为10 9 8 7 6 5 4 3 2 1
for (i = 0; i < 10; i++)
{
str[i] = 10 - i;
}
//排序,从a[0]开始排,从小到大
for (i = 0; i < 10; i++)
{
for (j = i + 1; j < 10; j++)
{
if (str[i] > str[j])
{
swap(&str[i], &str[j]);
}
}
}
//将十个数输出
for (i = 0; i < 10; i++)
printf("%d\n", str[i]);
return 0;
}
void swap(int *a, int *b)
{
int c;
c = *a;
*a = *b;
*b = c;
}

快速排序是冒泡排序的升级版,一般stl里使用的都是快排,效率还是可以的。
主要思想就是选择第一个数为标准数b,先从右开始找,找一个比b小的数赋值给left位上的数,也就是b,之后从左开始找,找一个比b大的数与right位上的数,因为right位上的数已经赋值给left了,所以其中right位置上的数是多余的,之后只要left<right就循环下去,当left == right的时候,将b赋值在left位上,现在的局面就是left左边都是比b小的,left右边都是比b大的。
然后在分别求两边的快排,写一个小递归就OK了,递归的退出条件就是left>right,其实就是已经将列表分解成单个数据的时候就退出递归,返回数据。
int quicksort(vector<int> &v, int left, int right){
if(left < right){
int key = v[left];
int low = left;
int high = right;
while(low < high){
while(low < high && v[high] > key){
high--;
}
v[low] = v[high];
while(low < high && v[low] < key){
low++;
}
v[high] = v[low];
}
v[low] = key;
quicksort(v,left,low-1);
quicksort(v,low+1,right);
}
}java版
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
namespace QuickSort
{
public class Program
{
static void Main(string[] args)
{
//5次比较
for (int i = 1; i <= 5; i++)
{
List<int> list = new List<int>();
//插入200个随机数到数组中
for (int j = 0; j < 200; j++)
{
Thread.Sleep(1);
list.Add(new Random((int)DateTime.Now.Ticks).Next(0, 10000));
}
Console.WriteLine("\n第" + i + "次比较:");
Stopwatch watch = new Stopwatch();
watch.Start();
var result = list.OrderBy(single => single).ToList();
watch.Stop();
Console.WriteLine("\n系统定义的快速排序耗费时间:" + watch.ElapsedMilliseconds);
Console.WriteLine("输出前是十个数:" + string.Join(",", result.Take(10).ToList()));
watch.Start();
new QuickSortClass().QuickSort(list, 0, list.Count - 1);
watch.Stop();
Console.WriteLine("\n俺自己写的快速排序耗费时间:" + watch.ElapsedMilliseconds);
Console.WriteLine("输出前是十个数:" + string.Join(",", list.Take(10).ToList()));
}
}
}
public class QuickSortClass
{
///<summary>
/// 分割函数
///</summary>
///<param name="list">待排序的数组</param>
///<param name="left">数组的左下标</param>
///<param name="right"></param>
///<returns></returns>
public int Division(List<int> list, int left, int right)
{
//首先挑选一个基准元素
int baseNum = list[left];
while (left < right)
{
//从数组的右端开始向前找,一直找到比base小的数字为止(包括base同等数)
while (left < right && list[right] >= baseNum)
right = right - 1;
//最终找到了比baseNum小的元素,要做的事情就是此元素放到base的位置
list[left] = list[right];
//从数组的左端开始向后找,一直找到比base大的数字为止(包括base同等数)
while (left < right && list[left] <= baseNum)
left = left + 1;
//最终找到了比baseNum大的元素,要做的事情就是将此元素放到最后的位置
list[right] = list[left];
}
//最后就是把baseNum放到该left的位置
list[left] = baseNum;
//最终,我们发现left位置的左侧数值部分比left小,left位置右侧数值比left大
//至此,我们完成了第一篇排序
return left;
}
public void QuickSort(List<int> list, int left, int right)
{
//左下标一定小于右下标,否则就超越了
if (left < right)
{
//对数组进行分割,取出下次分割的基准标号
int i = Division(list, left, right);
//对“基准标号“左侧的一组数值进行递归的切割,以至于将这些数值完整的排序
QuickSort(list, left, i - 1);
//对“基准标号“右侧的一组数值进行递归的切割,以至于将这些数值完整的排序
QuickSort(list, i + 1, right);
}
}
}
}版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:排序
原文地址:http://blog.csdn.net/djd1234567/article/details/47017559