单向线性链表的实现

/*
 * 练习:实现单向线性链表
 * list_append()  - 追加
 * list_size()    - 测长
 * list_print()   - 正向打印
 * list_rprint()  - 反向打印
 * list_reverse() - 逆转
 * list_middle()  - 中间值
 * list_merge()   - 将两个有序链表合并为一个有序链表
 */

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

/* 节点 */
typedef struct ListNode {
	int              data; /* 数据 */
	struct ListNode* next; /* 后指针 */
}	LIST_NODE;

/* 创建节点 */
LIST_NODE* create_node (int data) {
	LIST_NODE* node = malloc (sizeof (LIST_NODE));
	node->data = data;
	node->next = NULL;
}

/* 销毁节点 */
LIST_NODE* destroy_node (LIST_NODE* node) {
	LIST_NODE* next = node->next;
	free (node);
	return next;
}

/* 链表 */
typedef struct List {
	LIST_NODE* head; /* 头指针 */
	LIST_NODE* tail; /* 尾指针 */
}	LIST;

/* 初始化为空链表 */
void list_init (LIST* list) {
	list->head = NULL;
	list->tail = NULL;
}

/* 释放剩余节点并恢复到初始状态 */
void list_deinit (LIST* list) {
	while (list->head)
		list->head = destroy_node (list->head);
	list->tail = NULL;
}

/* 追加 */
void list_append (LIST* list, int data) {
	LIST_NODE* node = create_node (data);
	if (list->tail)
		list->tail->next = node;
	else
		list->head = node;
	list->tail = node;
}

/* 测长 */
size_t list_size (LIST* list) {
	size_t size = 0;
	LIST_NODE* node = NULL;
	for (node = list->head; node; node = node->next)
		++size;
	return size;
}

/* 正向打印 */
void list_print (LIST* list) {
	LIST_NODE* node = NULL;
	for (node = list->head; node; node = node->next)
		printf ("%d ", node->data);
	printf ("\n");
}

/* 反向打印以参数head的目标节点为首的子链表 */
void rprint (LIST_NODE* head) {
	if (head) {
		rprint (head->next);
		printf ("%d ", head->data);
	}
}

/* 反向打印 */
void list_rprint (LIST* list) {
	rprint (list->head);
	printf ("\n");
}

/* 逆转以参数head的目标节点为首的子链表 */
void reverse (LIST_NODE* head) {
	if (head && head->next) {
		reverse (head->next);
		head->next->next = head;
		head->next = NULL;
	}
}

/* 逆转 */
void list_reverse (LIST* list) {
	reverse (list->head);
	LIST_NODE* swap = list->head;
	list->head = list->tail;
	list->tail = swap;
}

/* 中间值 */
int list_middle (LIST* list) {
	LIST_NODE* mid = NULL, *node = NULL;
	for (mid = node = list->head; node->next &&
		node->next->next; node = node->next->next)
		mid = mid->next;
	return mid->data;
}

/* 将以参数head1的目标节点为首的子链表,与以参数
   head2的目标节点为首的子链表合并,保持合并结果
   有序,返回结果链表的首节点地址 */
LIST_NODE* merge (LIST_NODE* head1,
	LIST_NODE* head2) {
	if (! head1)
		return head2;
	if (! head2)
		return head1;
	LIST_NODE* head = NULL;
	if (head1->data < head2->data)
		(head = head1)->next =
			merge (head1->next, head2);
	else
		(head = head2)->next =
			merge (head2->next, head1);
	return head;
}

/* 合并 */
void list_merge (LIST* list1, LIST* list2) {
	list1->head = merge (list1->head, list2->head);
	if (list1->tail->data < list2->tail->data)
		list1->tail = list2->tail;
	list2->head = list2->tail = NULL;
}


/* 测试用例1 */
void test1 (void) {
	LIST list;
	list_init (&list);
	list_append (&list, 23);
	list_append (&list, 17);
	list_append (&list, 37);
	list_append (&list, 29);
	list_append (&list, 51);
	printf ("%u\n", list_size (&list));
	list_print (&list);
	list_rprint (&list);
	list_deinit (&list);
}

/* 测试用例2 */
void test2 (void) {
	LIST list;
	list_init (&list);
	int i;
	for (i = 0; i < 10; ++i)
		list_append (&list, i);
	list_print (&list);
	list_reverse (&list);
	list_print (&list);
	list_deinit (&list);
}

/* 测试用例3 */
void test3 (void) {
	LIST list;
	list_init (&list);
	int i ;
	for (i = 0; i < 11; ++i)
		list_append (&list, i);
	list_print (&list);
	printf ("%d\n", list_middle (&list));
	list_deinit (&list);
}

/* 测试用例4 */
void test4 (void) {
	LIST list1, list2;
	list_init (&list1);
	list_init (&list2);
	list_append (&list1, 11);
	list_append (&list1, 11);
	list_append (&list1, 29);
	list_append (&list1, 36);
	list_append (&list1, 36);
	list_append (&list2, 10);
	list_append (&list2, 11);
	list_append (&list2, 23);
	list_append (&list2, 34);
	list_append (&list2, 47);
	printf ("1:");
	list_print (&list1);
	printf ("2:");
	list_print (&list2);
	list_merge (&list1, &list2);
	printf ("1:");
	list_print (&list1);
	// 10 11 11 11 23 29 34 36 36 47
	printf ("2:");
	list_print (&list2);
	list_deinit (&list2);
	list_deinit (&list1);
}


int main (void) {
//	test1 ();
//	test2 ();
//	test3 ();
	test4 ();
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值