希尔排序(Shell Sort)

排序思想

先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量 dt=1(dt<dt-1…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。

复杂度:O(n3/2)。

稳定性:不稳定。

代码实例:

int[] list = { , , , , , ,  };
int len = list.Length;
int temp, j;
while (len > )
{
len = len / ;
for (int i = len; i < list.Length; i++)
{
if (list[i] < list[i - len])
{
temp = list[i];
for (j = i - len; j >= && temp < list[j]; j = j - len)
{
list[j + len] = list[j];
}
list[j + len] = temp;
}
}
}
Console.WriteLine("希尔排序的结果:{0}",string.Join(",", list));

堆排序(Heap Sort )

排序思想:指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。

堆是具有下列性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。

复杂度:O(nlogn)。

稳定性:不稳定。

堆排序只用做以下二点:

1:从无序序列中构建起大顶堆。

2:交换大顶堆中顶节点和后结点(n)位置,重新调整剩余元素,构建一个新的大顶堆。依次循环....

代码实例:

static void Main(string[] args)
{
int[] list = { , , , , , , };
for (int i = list.Length / - ; i >= ; i--) /* 构建大顶堆[list.Length / 2 - 1:无序数组中结点数]*/
{
HeapAdjust(list, i, list.Length);
} int temp;
for (int i = list.Length - ; i > ; i--) /* 替换大顶堆的位置,然后重新构建大顶堆。*/
{
temp = list[]; /* 替换大顶堆中最大值list[0]和最小值之前的位置list[i]*/
list[] = list[i];
list[i] = temp; HeapAdjust(list, , i); /* 重新构建大顶堆*/
} Console.WriteLine("堆排序的结果:{0}", string.Join(",", list));
} /// <summary>
/// 构建大顶堆
/// </summary>
/// <param name="list">排序集合</param>
/// <param name="NodeIndex">父结点</param>
/// <param name="len">大顶堆长度</param>
static void HeapAdjust(int[] list, int NodeIndex, int len)
{
int temp = list[NodeIndex]; /*二叉树节点值*/
for (int i = NodeIndex * + ; i < len; i = NodeIndex * + ) /*循环二叉树节点下左右孩子[NodeIndex*2+1找到结点下的左右孩子]*/
{
if (i + < len && list[i] < list[i + ]) /*i+1:是否存在左右两个孩子,list[i]<list[i+1]:默认左孩子大于右孩子*/
{
i++; /*左孩子小于右孩子直接i++ ,list[i]为右孩子值*/
} if (temp >= list[i]) /*节点大于等于(左/右)孩子直接退出不替换节点值*/
{
break;
} list[NodeIndex] = list[i]; /*替换节点和(左/右)孩子之间的值,保持结点大于左右孩子*/
NodeIndex = i; /*重新设置结点值,循环查询*/ }
list[NodeIndex] = temp; /*替换(左/右)孩子和结点之间的值*/
}

归并排序(Merge sort)

排序思想:“归并”一词的中文含义就是合并、并入的意思,而在数据结构中的定义是将两个或两个以上的有序表组合成一个新的有序表。
归并排序(Merging Sort)就是利用归并的思想实现的排序方法。它的原理是假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到⌈n/2⌉(⌈x⌉表示不小于x的最小整数)个长度为2或1的有序子序列;再两两归并,……,如此重复,直至得到一个长度为n的有序序列为止,这种排序方法称为2路归并排序。

复杂度:O(nlogn) 。

稳定性:稳定。

代码实例:

static void Main(string[] args)
{
int[] list = { , , , , , , }; MeSort(list, , list.Length - ); Console.WriteLine("归并排序的结果:{0}", string.Join(",", list));
} static void MeSort(int[] list, int start, int end)
{
if (start < end)
{
int middle = (start + end) / ; /*对数组进行分组*/
MeSort(list, start, middle); /*分组左序列*/
MeSort(list, middle + , end); /*分组右序列*/ MergeS(list, start, middle, end); /*对左右序列进行合并(归并)*/
}
} static void MergeS(int[] list, int first, int middle, int end)
{
int IndexA = first; /*左序列起始位置*/
int IndexB = middle + ; /*右序列起始位置*/
int[] tempList = new int[end - first + ]; /*左右序列合并后的临时数组*/
int tempIndex = ; while (IndexA <= middle && IndexB <= end) /*循环左右序列中的数据*/
{
if (list[IndexA] >= list[IndexB]) /*对比左右序列中数据大小*/
{
tempList[tempIndex++] = list[IndexB++]; /*右元素大于左元素,把右元素存放到临时数组tempList中,并把临时数组tempIndex++,然后在取右序列中下一元素*/
}
else
{
tempList[tempIndex++] = list[IndexA++]; /*左元素大于右元素,把左元素存放到临时数组tempList中,并把临时数组tempIndex++,然后在取在序列中下一元素*/
}
} while (IndexA <= middle) /*有一侧子表遍历完后,跳出循环,将另外一侧子表剩下的数一次放入暂存数组中*/
{
tempList[tempIndex++] = list[IndexA++];
} while (IndexB <= end)
{
tempList[tempIndex++] = list[IndexB++];
} tempIndex = ; /*设置临时数组从第1位开始替换*/
for (int i = first; i <= end; i++) /*临时数组替换List数组中数据*/
{
list[i] = tempList[tempIndex++];
}
}

快速排序(quick sort)

排序思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

复杂度:O(nlogn) 。

稳定性:不稳定。

代码实例:

static void Main(string[] args)
{
int[] list = { , , , , , , };
QuickSort(list, , list.Length - );
Console.WriteLine("快速排序的结果:{0}", string.Join(",", list));
} private static void QuickSort(int[] list, int start, int end)
{
int pivot;
if (start < end)
{
pivot = Partition(list, start, end); /* 对序列一分为二数出中间值 */
QuickSort(list, start, pivot - ); /* 对低端序列进行排序 */
QuickSort(list, pivot + , end); /* 对高端序列进行排序 */
}
} private static int Partition(int[] list, int first, int end)
{
int pivotkey = list[first]; /* 默认取序列中第0位为枢轴 */
while (first < end)
{
while (first < end && list[end] >= pivotkey) /*比枢轴小的记录交换到低端*/
{
end--;
}
swap(list, first, end); while (first < end && list[first] <= pivotkey) /*比枢轴大的记录交换到高端*/
{
first++;
}
swap(list, first, end);
}
return first; /*返回枢轴值*/
} /// <summary>
/// 替换数组A于B之间的位置
/// </summary>
private static void swap(int[] list, int A, int B)
{
int temp = list[A];
list[A] = list[B];
list[B] = temp;
}

常见排序方法基本就这些。已分享完毕.....

排序性能和速度快速排序优于其他常见排序方法。

C# 数据结构--排序[下]的更多相关文章

  1. 深入浅出Redis-redis底层数据结构(下)

    概述: 学习使用Redis,其实并不需要去研究其底层数据的实现.我们只需要了解他有哪些常用的数据类型,然后熟练使用,就可以很好的掌握Redis 这个工具了.但是这样的学习方法只适合Redis 的入门, ...

  2. C# 数据结构--排序[上]

    概述 看了几天的排序内容,现在和大家分享一些常见的排序方法. 啥是排序? 个人理解的排序:通过对数组中的值进行对比,交换位置最终得到一个有序的数组.排序分为内存排序和外部排序.本次分享排序方法都为内存 ...

  3. JS中的算法与数据结构——排序(Sort)(转)

    排序算法(Sort) 引言 我们平时对计算机中存储的数据执行的两种最常见的操作就是排序和查找,对于计算机的排序和查找的研究,自计算机诞生以来就没有停止过.如今又是大数据,云计算的时代,对数据的排序和查 ...

  4. JS中的算法与数据结构——排序(Sort)

    排序算法(Sort) 引言 我们平时对计算机中存储的数据执行的两种最常见的操作就是排序和查找,对于计算机的排序和查找的研究,自计算机诞生以来就没有停止过.如今又是大数据,云计算的时代,对数据的排序和查 ...

  5. 数据结构-排序-shell排序

    shell排序 首先,希尔排序适用于待排序列关键有序. 接下来一步步图解SHELL排序 我为了方便理解内部操作.我先把代码输出整理下. #include<iostream> #includ ...

  6. C数据结构排序算法——直接插入排序法用法总结(转http://blog.csdn.net/lg1259156776/)

    声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 排序相关的的基本概念 排序:将一组杂乱无章的数据按一定的规律顺次排列起来. 数据表( data list): ...

  7. 数据结构排序算法插入排序Java实现

    public class InsertDemo { public static void main(String args[]) { int[] sort ={4,2,1,3,6,5,9,8,10,7 ...

  8. Python 数据结构--排序

      各种排序的时间复杂度和空间复杂度   以下 冒泡排序,选择排序,插入排序,合并排序,快速排序,希尔排序   1 冒泡排序(Bubble Sort) 冒泡排序(Bubble Sort)是一种简单的排 ...

  9. PHP数组和数据结构(下)未完。。。。

    1.数组的遍历 (1)each(): 接受一个数组作为参数,返回数组中当前元素的键/值对,并向后移动数组指针到下一个元素的位置 键/值对被返回为带有四个元素的关联和索引混合的数组,键名分别为0,1,k ...

随机推荐

  1. Android渲染机制和丢帧分析

    http://blog.csdn.net/bd_zengxinxin/article/details/52525781 自己编写App的时候,有时会感觉界面卡顿,尤其是自定义View的时候,大多数是因 ...

  2. struts2中访问servlet API

    Struts2中的Action没有与任何Servlet API耦合,,但对于WEB应用的控制器而言,不访问Servlet API几乎是不可能的,例如需要跟踪HTTP Session状态等.Struts ...

  3. SSH连接 NAT型 VirtualBox + LINUX

    1.首先登录到虚拟机中的Linux系统,查看一下使用NAT网卡的IP地址. 2.关闭虚拟机. 3.依次点击 "设置 -> 网络 -> (网络地址转换)端口转发",其中需 ...

  4. 生成HTMLTestRunner测试报告的操作步骤——Python+selenium自动化

    HTMLTestRunner是Python标准库的unittest模块的一个扩展,具体操作如下 1.安装 环境:Window8 步骤:1)http://tungwaiyip.info/software ...

  5. 【风马一族_Android】Android Studio 给APP设置签名

    在Android Studio中,给App签名,如果没有给App设置签名的话,Android Studio会主动给app设置一个默认的签名 接下来,介绍主动给App设置一个签名的整个步骤过程: 1) ...

  6. Ubuntu下MySQL忘记root密码重置

    MySQL忘记root密码肿么办?-_-|||   这种情况虽然不是很常见,但是有时长时间没有登录系统,还真会忘记密码.这时候,如果您能以系统管理员权限登陆密码,那还是有救的.放大招,将其重置即可. ...

  7. silverlight 文本框只能输入汉字

    private void txtName_KeyDown(object sender, KeyEventArgs e) { Regex rg = new Regex("^[\u4e00-\u ...

  8. sql server 中更改默认实例

    因为安装了多个版本的sql server,会造成同时存在多个实例的情况. 1.关闭旧版本的sql server实例,并设置为手动启动 2.按下图步骤操作,把tcp端口设置为1433 3.重启sql s ...

  9. mysql删除、修改字段默认值

    alter table表名alter column字段名drop default; (若本身存在默认值,则先删除) alter table 表名 alter column 字段名 set defaul ...

  10. 正则PerlRegEx实现的批量替换指定文件中的标签

    示例: 一个朋友需要而编写的标签升级更新. 速度超快,1w个文件大概4,5秒,本想加个多线程显示进度,后来想想算了 主要代码: reg.RegEx := '<' + Edit_regular1. ...