实现不带头结点的单链表的快速排序
时间: 2023-06-03 14:03:25 浏览: 189
好的,以下是实现不带头结点的单链表的快速排序的代码示例(C语言实现):
```
#include <stdio.h>
#include <stdlib.h>
// 单链表结构体
struct LinkedList {
int value;
struct LinkedList *next;
};
// 分割链表,返回中间结点
struct LinkedList *partition(struct LinkedList *head, struct LinkedList *end, struct LinkedList **newHead, struct LinkedList **newEnd) {
struct LinkedList *pivot = end; // 选取最后一个节点作为pivot
struct LinkedList *prev = NULL;
struct LinkedList *cur = head; // cur 指向当前正在处理的结点
// 将小于pivot的结点移动到前部,大于pivot的结点移动到后部
while (cur != pivot) {
if (cur->value < pivot->value) {
// 将cur插入到newHead所指向的结点之前
if (*newHead == NULL) {
*newHead = cur;
}
prev = cur;
cur = cur->next;
} else {
// 将cur插入到newEnd所指向的结点之后
if (prev) {
prev->next = cur->next;
}
struct LinkedList *temp = cur->next;
cur->next = NULL;
(*newEnd)->next = cur;
(*newEnd) = cur;
cur = temp;
}
}
// 如果pivot是最小或最大的结点,需要单独处理
if (*newHead == NULL) {
*newHead = pivot;
}
*newEnd = pivot;
return pivot;
}
// 链表快速排序的递归函数
struct LinkedList *quickSortRecursive(struct LinkedList *head, struct LinkedList *end) {
// 如果链表为空或只有一个节点,直接返回
if (head == NULL || head == end) {
return head;
}
// 分割链表并获取中间结点
struct LinkedList *newHead = NULL;
struct LinkedList *newEnd = NULL;
struct LinkedList *pivot = partition(head, end, &newHead, &newEnd);
// 递归排序中间结点前面的链表和后面的链表
if (newHead != pivot) {
struct LinkedList *tmp = newHead;
while (tmp->next != pivot) {
tmp = tmp->next;
}
tmp->next = NULL;
newHead = quickSortRecursive(newHead, tmp);
tmp = getTail(newHead);
tmp->next = pivot;
}
pivot->next = quickSortRecursive(pivot->next, newEnd);
return newHead;
}
// 链表快速排序的入口函数
struct LinkedList *quickSort(struct LinkedList *head) {
return quickSortRecursive(head, getTail(head));
}
// 创建链表结点
struct LinkedList *createNode(int value) {
struct LinkedList *newNode = (struct LinkedList*)malloc(sizeof(struct LinkedList));
newNode->value = value;
newNode->next = NULL;
return newNode;
}
// 将新结点插入到链表末尾
void pushBack(struct LinkedList **head, struct LinkedList **tail, int value) {
struct LinkedList *newNode = createNode(value);
if (*head == NULL) {
*head = newNode;
*tail = newNode;
return;
}
(*tail)->next = newNode;
*tail = newNode;
}
// 获取链表末尾结点
struct LinkedList *getTail(struct LinkedList *head) {
while (head != NULL && head->next != NULL) {
head = head->next;
}
return head;
}
// 打印链表
void printList(struct LinkedList *head) {
while (head != NULL) {
printf("%d ", head->value);
head = head->next;
}
printf("\n");
}
int main() {
struct LinkedList *head = NULL;
struct LinkedList *tail = NULL;
// 创建链表
pushBack(&head, &tail, 3);
pushBack(&head, &tail, 2);
pushBack(&head, &tail, 1);
pushBack(&head, &tail, 5);
pushBack(&head, &tail, 4);
// 打印原链表
printf("原链表:");
printList(head);
// 对链表进行快速排序
head = quickSort(head);
// 打印排序后的链表
printf("排序后的链表:");
printList(head);
// 释放链表内存
while (head != NULL) {
struct LinkedList *temp = head;
head = head->next;
free(temp);
}
return 0;
}
```
希望这个示例代码能够帮助你了解如何实现不带头结点的单链表的快速排序。如果还有其他问题,请随时提问。
阅读全文