c语言双向链表 快速排序,双向链表的快速排序(swift版本)

面试经常会被问到的单向链表的快速排序or双向链表的快速排序,现在用swift写了一个双向链表的快速排序,直接上代码

获取源码

//初始化

var linkList = LinkList()

linkList.append(value: 12)

linkList.append(value: 5)

linkList.append(value: 30)

linkList.append(value: 3)

linkList.append(value: 3)

linkList.append(value: 2)

linkList.append(value: 9)

linkList.append(value: 4)

linkList.append(value: 11)

linkList.append(value: 19)

linkList.append(value: 15)

linkList.append(value: 16)

print("Init Data: \(linkList)")

var firstNode = linkList.searchIndex(index: 0)

var endNode = linkList.searchIndex(index: linkList.linkListSize() - 1)

quickSort(linkList: &linkList, low: &firstNode, high: &endNode)

print("After QuickSort: \(linkList)")

// Print效果

Init Data: [Optional(12), Optional(5), Optional(30), Optional(3), Optional(3), Optional(2), Optional(9), Optional(4), Optional(11), Optional(19), Optional(15), Optional(16)]

After QuickSort: [Optional(2), Optional(3), Optional(3), Optional(4), Optional(5), Optional(9), Optional(11), Optional(12), Optional(15), Optional(16), Optional(19), Optional(30)]

Program ended with exit code: 0

class Node {

var value: T

var next: Node?

weak var previous: Node?

init(value: T) {

self.value = value

}

}

class LinkList {

var head: Node?

var tail: Node?

// Add

func append(value: T) {

let newNode = Node.init(value: value)

if let tailNode = tail {

newNode.previous = tailNode

tailNode.next = newNode

}

else {

head = newNode

}

tail = newNode

}

// Size

func linkListSize() -> Int {

if let node = head {

var index = 1

var node = node.next

while node != nil {

index += 1

node = node?.next

}

return index

}

else {

return 0

}

}

// Search

func searchNode(indexNode: Node) -> Int {

if let node = head {

if node === indexNode {

return 0

}

else {

var index: Int = 0

var node = node.next

while node != nil {

index += 1

if node === indexNode {

return index

}

node = node?.next

}

// 不存在返回-1

return -1

}

}

else {

// 不存在返回-1

return -1

}

}

func lowBeforeHigh(low: Node, high: Node) -> Bool {

if low === high {

return false

}

else {

var node = low.next

while node != nil {

if node === high {

return true

}

node = node?.next

}

}

return false

}

func searchIndex(index: Int) -> Node? {

if let node = head {

if index == 0 {

return node

}

else {

var node = node.next

var nodeIndex: Int = 1

while node != nil {

if nodeIndex == index {

return node

}

nodeIndex += 1

node = node?.next

}

return nil

}

}

else {

return nil

}

}

// Remove

func remove(node: Node) -> T {

let preNode = node.previous

let nextNode = node.next

if let preNode = preNode {

// 前节点存在

preNode.next = nextNode

}

else {

// 不存在前节点,将nextNode置成head

head = nextNode

}

nextNode?.previous = preNode

if nextNode == nil {

tail = preNode

}

// 将node置成nil

node.previous = nil

node.next = nil

return node.value

}

func removeAll() {

head = nil

tail = nil

}

}

//MARK: - QuickSort

func quickSort(linkList: inout LinkList, low: inout Node?, high: inout Node?) {

guard linkList.head != nil && linkList.tail != nil else {

return

}

guard low != nil && high != nil else {

return

}

guard linkList.lowBeforeHigh(low: low!, high: high!) else {

return

}

let midIndex = partition(linkList: &linkList, low: &low!, high: &high!)

// 递归

quickSort(linkList: &linkList, low: &low, high: &linkList.searchIndex(index: midIndex )!.previous)

quickSort(linkList: &linkList, low: &linkList.searchIndex(index: midIndex)!.next, high: &high)

}

func partition(linkList: inout LinkList, low: inout Node, high: inout Node) -> Int {

var value: Int = 0

var lowNode = low

var highNode = high

let lowValue = low.value

while linkList.lowBeforeHigh(low: lowNode, high: highNode) {

// 从右边向左边扫描

while linkList.lowBeforeHigh(low: lowNode, high: highNode) && highNode.value >= lowValue {

highNode = highNode.previous!

}

if highNode === lowNode {

value = linkList.searchNode(indexNode: lowNode)

break

}

// lowNode和highNode交换值

let temp1Value = lowNode.value

lowNode.value = highNode.value

highNode.value = temp1Value

// 从左边向右边扫描

while linkList.lowBeforeHigh(low: lowNode, high: highNode) && lowNode.value <= lowValue {

lowNode = lowNode.next!

}

if lowNode === highNode {

value = linkList.searchNode(indexNode: lowNode)

break

}

// lowNode和highNode交换值

let temp2Value = lowNode.value

lowNode.value = highNode.value

highNode.value = temp2Value

}

return value

}

func swapTwoNode(low: inout Node, high: inout Node) {

// 相邻节点

if low.next === high {

low.previous?.next = high

high.previous = low.previous

low.previous = high

low.next = high.next

high.next?.previous = low

high.next = low

}

else {

// 非相邻节点

low.previous?.next = high

low.next?.previous = high

high.next?.previous = low

high.previous?.next = low

let temp1 = low.previous

low.previous = high.previous

high.previous = temp1

let temp2 = low.next

low.next = high.next

high.next = temp2

}

}

以下是 C 语言双向链表快速排序实现: ```c #include <stdio.h> #include <stdlib.h> typedef struct node { int val; struct node *prev; struct node *next; } Node; Node *partition(Node *head, Node *tail) { int pivot = tail->val; Node *i = head->prev; for (Node *j = head; j != tail; j = j->next) { if (j->val <= pivot) { i = (i == NULL) ? head : i->next; int tmp = i->val; i->val = j->val; j->val = tmp; } } i = (i == NULL) ? head : i->next; int tmp = i->val; i->val = tail->val; tail->val = tmp; return i; } void quick_sort(Node *head, Node *tail) { if (tail != NULL && head != tail && head != tail->next) { Node *p = partition(head, tail); quick_sort(head, p->prev); quick_sort(p->next, tail); } } void print_list(Node *head) { while (head != NULL) { printf("%d ", head->val); head = head->next; } printf("\n"); } int main() { Node *head = (Node *)malloc(sizeof(Node)); head->val = 5; head->prev = NULL; head->next = (Node *)malloc(sizeof(Node)); head->next->val = 2; head->next->prev = head; head->next->next = (Node *)malloc(sizeof(Node)); head->next->next->val = 8; head->next->next->prev = head->next; head->next->next->next = (Node *)malloc(sizeof(Node)); head->next->next->next->val = 3; head->next->next->next->prev = head->next->next; head->next->next->next->next = NULL; printf("Before sorting: "); print_list(head); quick_sort(head, head->next->next->next); printf("After sorting: "); print_list(head); return 0; } ``` 解释: - `partition` 函数实现了快速排序的分区操作,其输入参数为链表头和尾节点,返回值为分区点; - `quick_sort` 函数实现了快速排序的递归操作; - `print_list` 函数用于打印链表; - 在 `main` 函数中初始化了一个双向链表,并对其进行排序。 注意: - 在 `partition` 函数中,我们选择尾节点作为基准点(pivot),这是快速排序的常规选择; - 在 `partition` 函数中,我们使用了一种经典的双指针算法,分别指向小于等于基准点和大于基准点的元素; - 在 `partition` 函数中,我们使用了链表节点值的交换,而不是节点指针的交换,因为我们需要维护链表节点的 prev 和 next 指针; - 在 `quick_sort` 函数中,我们需要判断链表头和尾是否相等,以及链表头是否为尾的下一个节点,这是递归终止条件; - 在 `main` 函数中,我们需要手动创建链表并初始化,这是为了方便演示。在实际应用中,链表可能是从其他函数或模块中传入的,或者是动态创建的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值