您的位置:首页 > 其它

小练习 - 单链表冒泡排序,交换指针域

2018-02-18 14:29 309 查看
链表的排序,好的做法是交换指针域。链表节点的数据域可能比较大,交换数据域可能会涉及拷贝过多的内存,影响性能。链表是链式存储,无法随机访问(base_addr + offset), 所以比较适合的办法是用比较两两相邻节点的冒泡排序法。当然还有一个办法就是,把所有的链表地址存到一个数组里,排序后重新遍历设置所有指针域,这个就多了两次遍历,也可以。下面是交换指针域的一个单链表冒泡排序的例子:

#include <stdio.h>
#include <stdlib.h>

struct Node {
int data;
struct Node *next;
};

struct Node *listHead = NULL;
struct Node *listTail = NULL;

/* 交换指针域,冒泡排序单链表 */
void sortList()
{
struct Node *cur, *prev, *tmp, *last;
cur = listHead;
prev = listHead;
last = NULL;
int i = 0, j = 0;

while (cur != last) {
i = 0;
while (cur != NULL && cur->next != last) {
if (cur->data > cur->next->data) {
/* cur, cur->next 交换位置 */
tmp = cur->next;
cur->next = cur->next->next;
tmp->next = cur;
if (i > 0)
prev->next = tmp;  /* 第一次交换: prev == cur */

/* 移动 prev, cur 节点,这里cur已经是下一个 */
prev = tmp;

/* 维护头结点 */
if (i == 0)
listHead = prev;
} else {
/* 节点不交换位置 */
prev = cur;
cur = cur->next;
}
i++;
}

/* 维护尾节点 */
if (j++ == 0) {
listTail = cur;
listTail->next = NULL;
}

last = cur;
cur = listHead;
prev = listHead;
}
}

void initList()
{
size_t i;
struct Node *node;
int nums[] = {8, 7, 6, 5, 0, 2, 3, 9, 4, 1};
for (i = 0; i < sizeof(nums) / sizeof(int); i++) {
node = (struct Node*)malloc(sizeof(struct Node));
node->data = nums[i];
node->next = NULL;
if (listHead == NULL) {
listHead = node;
}
if (listTail == NULL) {
listTail = node;
} else {
listTail->next = node;
listTail = node;
}
}
}

void printList()
{
struct Node *node;
node = listHead;
while (node != NULL) {
printf("%d ", node->data);
node = node->next;
}
printf("\n");
}

int main()
{
initList();
printf("before: ");
printList();
sortList();
printf("after : ");
printList();
printf("head %d, tail %d\n", listHead->data, listTail->data);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: