#include <stdlib.h> /* malloc */
#include <stdio.h>
typedef struct _node {
int data;
struct _node *next;
} node;
/* 此程序中的单链表带头结点.
* 基本操作:
* 创建
* 插入
* 删除
* 长度
* 打印
* 排序
* 逆置
* 求中
* 合并
* 去重
*/
node *create(int num);
void print(node *L);
int getlength(node *L);
node *delete(node *L, int val);
node *insert(node *L, int val);
node *sort(node *L);
node *reverse(node *L);
int getmid(node *L);
node *merge(node *L1, node *L2);
node *delrepeat(node *L);
int main()
{
int count, val;
node *list_a, *list_b, *list_c;
printf("Input node number: ");
scanf("%d", &count);
list_a = create(count);
printf("Original list: ");
print(list_a);
val = getmid(list_a);
printf("Middle value = %d/n", val);
int len;
len = getlength(list_a);
printf("Len = %d/n", len);
printf("Reversing result: ");
reverse(list_a);
print(list_a);
printf("Sorting result: ");
sort(list_a);
print(list_a);
printf("Input value to delete: ");
scanf("%d", &val);
delete(list_a, val);
print(list_a);
printf("Input value to insert: ");
scanf("%d", &val);
insert(list_a, val);
print(list_a);
printf("Input node number(list_b): ");
scanf("%d", &count);
list_b = create(count);
sort(list_b);
printf("Original list(list_a and list_b): /n");
print(list_a);
print(list_b);
list_c = merge(list_a, list_b);
printf("Merge result: ");
print(list_c);
printf("Delete repeat result: ");
delrepeat(list_c);
print(list_c);
return 0;
}
/* Create */
node *create(int num)
{
node *head, *p, *n;
head = (node *)malloc(sizeof(node)); // remember head node has no data.
p = head;
while (num > 0)
{
n = (node *)malloc(sizeof(node));
printf("Input: ");
scanf("%d", &(n->data));
p->next = n; // 连接到尾部
p = n;
num--;
}
p->next = NULL;
return head;
}
/* Print */
void print(node *L)
{
node *it;
if (L->next != NULL)
{
it = L->next;
while (it != NULL)
{
printf("%d ", it->data);
it = it->next;
}
printf("/n");
}
else
printf("This is a empty List./n");
return;
}
int getlength(node *L) // not include head node.
{
node *it = L->next;
int len = 0;
while (it != NULL)
{
len++;
it = it->next;
}
return len;
}
node *sort(node *L)
{
int t, i, j, flag, len = 0;
node *head, *p;
head = L;
p = L->next;
while (p != NULL)
{
len++;
p = p->next;
}
if (len<2) // 少于2个节点直接不处理.
return (head);
p = L->next;
for (i=1; i<len; i++) // 使用冒泡排序.
{
flag = 0;
p = L->next; // 归位, 非常重要!!!
for (j=1; j<len-i+1; j++)
{
if (p->data > p->next->data)
{
flag = 1;
t = p->data;
p->data = p->next->data;
p->next->data = t;
}
p = p->next;
}
if (flag == 0)
break;
}
return (head);
}
/* 前提是单链表是有序的, 单调不减. 使用sort() */
node *delete(node *L, int val)
{
node *head, *p, *b;
head = L;
b = L;
p = b->next;
while (p != NULL && p->data != val)
{
b = p;
p = p->next;
}
if (p != NULL)
{
b->next = p->next;
free(p);
p = NULL;
}
else
printf("Not find node of value: %d/n", val);
return (head);
}
/* 前提是单链表是有序的, 单调不减. 使用sort() */
node *insert(node *L, int val)
{
node *head, *p, *b;
head = L;
b = L;
p = b->next;
node *n = (node*)malloc(sizeof(node));
n->data = val;
n->next = NULL;
while(p != NULL && p->data < val)
{
b = p;
p = p->next;
}
if (p != NULL)
{
b->next = n;
n->next = p;
}
else
{
b->next = n;
}
return (head);
}
node *reverse(node *L)
{
node *head, *b, *p, *n;
head = L;
b = NULL; // important.尾指针
p = head->next;
if (p == NULL || p->next == NULL) // node number<2
return (head);
n = p->next;
while (p->next != NULL)
{
p->next = b;
b = p;
p = n;
n = p->next;
}
p->next = b; // important, 否则只得到一个节点,其他的都会丢掉.
head->next = p;
return (head);
}
int getmid(node *L) // 按照中间点 = n/2原则
{
node *mid, *p;
mid = p = L->next;
while (p != NULL && p->next != NULL && p->next->next != NULL)
{
p = p->next->next;
mid = mid->next;
}
return (mid->data);
}
node *merge(node *L1, node *L2) // 如果允许重复, 不需要free任何节点.
{
node *head, *p, *p1, *p2, *d;
head = p = L1;
p1 = L1->next;
p2 = L2->next;
while (p1 != NULL && p2 != NULL)
{
if (p1->data < p2->data)
{
p->next = p1;
p = p1;
p1 = p1->next;
}
else if (p1->data > p2->data)
{
p->next = p2;
p = p2;
p2 = p2->next;
}
else
{
p->next = p1;
p = p1;
p1 = p1->next;
p->next = p2;
p = p2;
p2 = p2->next;
}
} // end of while.
if (p1 != NULL)
p->next = p1;
if (p2 != NULL)
p->next = p2;
free(L2); // 将L2头节点释放!
L2 = NULL;
return (head);
}
node *delrepeat(node *L) // 在有序的基础之上进行.
{
node *head, *p, *n, *t;
head = L;
p = head->next;
while (p != NULL && p->next != NULL)
{
n = p->next;
while (n != NULL && p->data == n->data)
{
t = n;
n = n->next;
free(t);
t = NULL;
p->next = n;
}
p = p->next;
}
// p->next = NULL; // 情形: 1. 最后结点保留; 2. 最后结点删除, 则此时已有p=NULL.
return (head);
}
本文介绍了一个简单的单链表实现,包括创建、打印、求长度、插入、删除、排序、逆置、求中值、合并及去重等基本操作。通过具体示例展示了如何运用这些功能。
561

被折叠的 条评论
为什么被折叠?



