您的位置:首页 > 其它

经典算法之七大排序

2015-05-18 20:59 190 查看
【交换排序】:冒泡排序,快速排序 【选择排序】:简单选择排序,堆排序

【插入排序】:简单插入排序,希尔排序 ;归并排序

一:交换排序

public class BubbleSort
{
public static List<int> Sort(List<int> list)
{
int temp = 0;
//要比较的次数 n-1
for (int i = 0; i < list.Count - 1; i++)
{
//从底部开始
for (int j = list.Count - 1; j > i; j--)
{
//往下沉
if (list[j - 1]>list[j])
{
temp = list[j];
list[j] = list[j - 1];
list[j - 1] = temp;
}
}
}
return list;
}
}


 快排

1  public class QuickSort
2     {
3         public static void Sort(List<int> list,int left,int right)
4         {
5             if (left < right)
6             {
7                 int i = Division(list, left, right);
8                 Sort(list, left, i - 1);
9                 Sort(list,i+1,right);
10             }
11         }
12
13         private static int Division(List<int> list, int left, int right)
14         {
15             //挑选基准元素
16             int baseNum = list[left];
17
18             while (left < right)
19             {
20                 //从数组的右端开始向前找,一直找到比base小的数字为止
21                 while (left < right && list[right] >= baseNum)
22                 {
23                     right = right - 1;
24                 }
25                 list[left] = list[right];
26
27                 while (left < right && list[left] <= baseNum)
28                 {
29                     left = left + 1;
30                 }
31                 list[right] = list[left];
32             }
33
34             list[left] = baseNum;
35
36             return left;
37         }


二:选择排序:

1  public class SelectionSort
2     {
3         static void Sort(List<int> list)
4         {
5             for (int i = 0; i < list.Count - 1; i++)
6             {
7                 //设置tempIndex的下标值
8                 int tempIndex = i;
9                 for (int j = i + 1; j < list.Count; j++)
10                 {
11                     if (list[tempIndex] > list[j])
12                     {
13                         tempIndex = j;
14                     }
15                 }
16
17                 var tempData = list[tempIndex];
18                 list[tempIndex] = list[i];
19                 list[i] = tempData;
20             }
21         }


/// <summary>
/// 堆排序(大根堆,小根堆)
/// 大根堆(父结点比孩子结点都要大)
/// 小跟堆(父结点比孩子结点都要小)
/// </summary>
public class HeapSort
{
public static void Sort(List<int> list)
{
//list.Count/2-1:就是堆中父节点的个数
for (int i = list.Count / 2 - 1; i >= 0; i--)
{
HeapAdjust(list, i, list.Count);
}

//最后输出堆
for (int i = list.Count - 1; i > 0; i--)
{
//堆顶与当前堆的第i个元素值对调,将对顶踢出,破换堆
int temp = list[0];
list[0] = list[i];
list[i] = temp;

//因为两值交换,可能破坏根堆,所以必须重新构造
HeapAdjust(list, 0, i);
}

}

private static void HeapAdjust(List<int> list, int parent, int length)
{
//temp保留当前父结点
int temp = list[parent];

//得到左孩子(二叉树的定义)
int child = 2 * parent + 1;

while (child < length)
{
//如果parent有右孩子,则判断左孩子是否小于右孩子
if (child + 1 < length && list[child] < list[child + 1])
child++;

if (temp > list[child])
break;

//将较大结点的值赋给父结点
list[parent] = list[child];

//然后将子节点做为父亲节点,已防止是否破坏根堆时重新构造
parent = child;

//找到该父亲节点较小的左孩子节点
child = 2 * parent + 1;
}
//最后将temp值赋给较大的子结点,形成两值交换
list[parent] = temp;
}

}


三:插入排序

/// <summary>
/// 插入排序
/// </summary>
/// <remarks>
/// 数组被划分为无序数组块和有序数组块
/// </remarks>
public class InsertSort
{
static void Sort(List<int> list)
{
//无序序列
for (int i = 1; i < list.Count; i++)
{
var temp = list[i];
int j;

//有序序列
for (j = i - 1; j >= 0 && temp < list[j]; j--)
{
list[j + 1] = list[j];
}
list[j + 1] = temp;

}
}
}


public class ShellSort
{
static void Sort(List<int> list)
{
//取增量
int step = list.Count/ 2;

while (step >= 1)
{
for (int i = step; i < list.Count; i++)
{
int temp = list[i];
int j;
for (j = i - step; j >= 0 && temp < list[j]; j = j - step)
{
list[j + step] = list[j];
}
list[j + step] = temp;
}
step = step / 2;
}
}
}


四:归并排序

/// <summary>
/// 归并排序的过程
/// 第一: “分”,  就是将数组尽可能的分,一直分到原子级别。
///第二: “并”,将原子级别的数两两合并排序,最后产生结果。
/// </summary>
public class MergeSort
{
static void Sort(int[] array, int[] temparray, int left, int right)
{
if (left < right)
{
//取分割位置
int middle = (left + right) / 2;

//先递
Sort(array, temparray, left, middle);

Sort(array, temparray, middle + 1, right);

//后归
Merge(array, temparray, left, middle + 1, right);
}
}

//数组的两两合并操作
private static void Merge(int[] array, int[] temparray, int left, int middle, int right)
{
//左指针尾
int leftEnd = middle - 1;
//右指针头
int rightStart = middle;

//临时数组的下标
int tempIndex = left;

//数组合并后的length长度
int tempLength = right - left + 1;

//先循环两个区间都没有结束的情况
while ((left <= leftEnd) && (rightStart <= right))
{
if (array[left] < array[rightStart])
{
temparray[tempIndex++] = array[left++];
}
else
{
temparray[tempIndex++] = array[rightStart++];
}
}

//判断左序列是否结束
while (left <= leftEnd)
temparray[tempIndex++] = array[left++];

while (rightStart <= right)
temparray[tempIndex++] = array[rightStart++];

//交换数据
for (int i = 0; i < tempLength; i++)
{
array[right] = temparray[right];
right--;
}

}
}


 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: