C#,双向链表(Doubly Linked List)快速排序(Quick Sort)算法与源代码
双向链表
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
循环链表是一种链式存储结构,它的最后一个结点指向头结点,形成一个环。因此,从循环链表中的任何一个结点出发都能找到任何其他结点。循环链表的操作和单链表的操作基本一致,差别仅仅在于算法中的循环条件有所不同。
快速排序(Quick Sort)
快速排序是非常流行、应用非常广泛的排序算法,而且实现简单,适用于各种不同的输入数据,在一般应用中比其他排序算法都要快很多。快速排序是基于分治思想的原地排序的排序算法,将长度为N的数组排序所需时间和NlgN成正比,而且内循环比大多数排序算法都要短小和简单,因此一般情况比其他排序算法效率高。它的缺点是非常脆弱,某些情况可能导致它的性能达到平方级别,因此实现时必须非常小心才能避免低劣的性能。
快速排序的整体思路是根据某个元素将一个数组分成左右两个子数组,以该元素为界限,左侧子数组的值都小于或等于该元素,右侧子数组的值都大于或等于该元素(这一过程称为切分,下面会介绍)。然后递归地对数组的左右两个子数组继续进行上述操作,直到所有元素排列完成。上述每一趟切分都能排定一个元素(切分元素),如果左子数组和右子数组都是有序的,那么由左子数组、切分元素、右子数组组成的数组一定是有序的。
切分的详细过程
一般选取数组第一个元素为切分元素,也是那个会被排定的元素,然后定义两个指针,一个指针从数组左侧第二个元素开始向右侧遍历数组,直到找到一个大于或等于切分元素的元素时停止;另一个指针从数组右侧最后一个元素开始向左侧遍历数组,直到找到一个小于或等于切分元素的元素时停止,然后交换两个元素的位置。如此继续,直到两个指针相遇,然后将切分元素和左子数组最右侧元素交换位置,并返回交换后的切分元素位置即可。这样每一趟切分都能排定切分元素,并保证切分元素左侧的元素都小于或等于它,右侧的元素都大于或等于它。
源程序
public class DoublyLinkNode
{
public int Data { get; set; } = 0;
public DoublyLinkNode Next { get; set; } = null;
public DoublyLinkNode Prev { get; set; } = null;
public DoublyLinkNode(int d)
{
Data = d;
}
}
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
namespace Legalsoft.Truffer.Algorithm
{
public partial class DoublyLinkedList
{
private DoublyLinkNode LastNode(DoublyLinkNode node)
{
while (node.Next != null)
{
node = node.Next;
}
return node;
}
private DoublyLinkNode Partition(DoublyLinkNode last, DoublyLinkNode head)
{
int pivot = head.Data;
DoublyLinkNode i = last.Prev;
for (DoublyLinkNode j = last; j != head; j = j.Next)
{
if (j.Data <= pivot)
{
// Similar to i++ for array
i = (i == null) ? last : i.Next;
{
int temp = i.Data;
i.Data = j.Data;
j.Data = temp;
}
}
}
i = (i == null) ? last : i.Next;
{
int temp = i.Data;
i.Data = head.Data;
head.Data = temp;
}
return i;
}
private void QuickSort_Utility(DoublyLinkNode last, DoublyLinkNode head)
{
if (head != null && last != head && last != head.Next)
{
DoublyLinkNode temp = Partition(last, head);
QuickSort_Utility(last, temp.Prev);
QuickSort_Utility(temp.Next, head);
}
}
public void QuickSort(DoublyLinkNode node)
{
DoublyLinkNode head = LastNode(node);
QuickSort_Utility(node, head);
}
public DoublyLinkNode Push(DoublyLinkNode head, int d)
{
DoublyLinkNode node = new DoublyLinkNode(d);
node.Next = head;
head.Prev = node;
return node;
}
}
}
相关文章
- pattern matching is C# 7.0
- c#打包文件解压缩 C#中使用委托、接口、匿名方法、泛型委托实现加减乘除算法 一个简单例子理解C#的协变和逆变 对于过长字符串的大小比对
- ASP.NET MVC Filters 4种默认过滤器的使用【附示例】 数据库常见死锁原因及处理 .NET源码中的链表 多线程下C#如何保证线程安全? .net实现支付宝在线支付 彻头彻尾理解单例模式与多线程 App.Config详解及读写操作 判断客户端是iOS还是Android,判断是不是在微信浏览器打开
- 浅谈c#的三个高级参数ref out 和Params C#中is与as的区别分析 “登陆”与“登录”有何区别 经典SQL语句大全(绝对的经典)
- 【卷土重来之C#学习笔记】(二)c#编程概述
- C#,巴都万数列(Padonve Number)的算法与源代码
- C#,单向链表(Simply Linked List)的归并排序(Merge Sort)算法与源代码
- 《C#多线程编程实战(原书第2版)》——1.11 使用Monitor类锁定资源
- 《C#多线程编程实战(原书第2版)》——3.5 实现一个取消选项
- C# Html Agility Pack
- C#使用Mutex实例详解
- C#接口中为什么不能像java那样使用static?
- C# 配置文件读取与修改
- c# winform 中的坐标系
- C# 窗口背景 短消息提示
- C# 字符串转义和反转义
- 基于C#实现(WinForm)求解SIN(X)数值分析【100010739】
- c#字面量
- C#Windows服务程序安装常见问题解决方法
- 堆排序 -- C#代码实现
- C#程序之Main()方法
- c# 钩子类
- C# 链表操作
- c#类的定义,c#中的关健字,C#标识符