链表(一) 单链表的基本操作

单链表的基本操作: 

                --- 包括插入,删除,遍历等,最后有一个非递减链表的合并。

                --- 注:使用的结构是带头节点的链表;

                           插入时:头插法的时间复杂度小于尾插,注意勾连顺序。

                           删除时:注意双指针的移动,头删时头相当于另一个指针。

                    将表置空时:需要特别注意的是将head - next置空。

                               

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

#define   Elemtype int


/*-----------单链表结构------------*/
typedef struct node  {
	Elemtype data;
	struct node* next;
}Node;

/*---------初始化为有头单链表-------------*/
Node* init_Link_list()
{
	Node * head = (Node*)malloc(sizeof(Node));
	if (NULL == head) {
		printf("init error\n");
		exit(-1);
	}
	head->next = NULL;
	return head;
}
/*-------------创建节点-----------------*/
Node* create_Node()
{
	Node *p= NULL;
	while (p == NULL)
	{
		p = (Node*)malloc(sizeof(Node));
	}
	p->next = NULL;
	return p;
}

/*-------------头插-------------------*/
void insert_H_list(Node* head,Elemtype val)
{
	if (head == NULL) {
		printf("list error\n");
		return;
	}
	Node* New = create_Node();
	New->data = val;
	New->next = head->next;/*勾链*/
	head->next = New;
}
/*-----------------获取尾节点-------------*/
Node* get_T_list(Node* head)
{
	Node* p = head;
	while (p->next != NULL)
		p = p->next;
	return p;
}

/*---------------尾插------------------*/
void insert_T_list(Node* head, Elemtype val)
{

	if (head == NULL) {
		printf("head is empty\n");
		return;
	}
	Node* New = create_Node();
	New->data = val;
	Node* p = get_T_list(head);
	/*------勾链-------*/
	p->next = New;
	/*   New的指针在创建的时候最好置空
	     防止野指针的出现    */		
}
/*-------------遍历-----------------------*/
void print_list(Node* head)
{
	if (head->next == NULL) {
		printf("list is empty\n");
		return;
	}
	Node* p = head->next;
	/*开始遍历,此处遍历可以传入一个函数指针,程序会更加灵活*/
	while (p!=NULL)
	{
		printf("%3d", p->data);
		p = p->next;
	}
	printf("\n");

}
/*---------------将表置空-------------*/
void set_Empty(Node* head)
{
	if (head != NULL)
	{
		Node* p = head;
		/*---------清空--------*/
		while (head->next != NULL)
		{
			p = head->next;
			head->next = p->next;
			free(p);
		}
		head->next;/*注意将头置空*/
	}
}
/*---------------尾删除------------------*/
void dele_T_list(Node* head)
{
	if (head == NULL)
	{
		return;
	}
	/*单链表的删除:
			除了头删法都要用到双指针
			(这个缺陷可以用双向链表弥补)
			*/
	Node* p = head;
	Node* d = p->next;
	while (d->next != NULL)
	{
		/*在不删除时双指针步调不分先后*/
		d = d->next;
		p = p->next;
	}
	p->next = NULL;
	free(d);
	
}
/*----------------查找定位删除--------------*/
void delete_val_list(Node* head, Elemtype val)
{
	if (head == NULL)
	{
		printf("NO val :%d\n", val);
		return;
	}
	Node* p = head;

	Node*  d= head->next;
	while (d != NULL)
	{
		if (val == d->data)
		{/*------删除-----*/
			p->next = d->next;
			free(d);d = NULL;
			return;   /*全删除时在此处更改,继续删除*/
		}
		p = p->next;
		d = d->next;
	}
	/*-----当链表中不存在val时*--*/
	printf("NO val :%d\n", val);
}
/*---------------两个非递减的链表合并---------*/
void marge_list(Node* La, Node* Lb, Node* Lc)
{
	Node* pa = La->next;
	Node* pb = Lb->next;
	Node* pc = Lc;
	while (pa != NULL&&pb != NULL)
	{
		if (pa->data <= pb->data) {
			pc->next = pa;/*挂链*/
			pa = pa->next;/*pa后移*/
			pc = pc->next;/*更新pc*/
		}
		else {
			pc->next = pb;/*挂链*/
			pb = pb->next;/*pa后移*/
			pc = pc->next;/*更新pc*/
		}
	}
	/*将剩余节点挂链*/
	while(pa != NULL) {
		pc->next = pa;/*挂链*/
		pa = pa->next;/*pa后移*/
		pc = pc->next;/*更新pc*/
	}
	while (pb != NULL) {
		pc->next = pb;/*挂链*/
		pb = pb->next;/*pa后移*/
		pc = pc->next;/*更新pc*/
	}
}

int main()
{
	//Node* head = init_Link_list();
	/*for (int i = 1;i < 8;i++)
	{
		insert_H_list(head, i);
	}
	/*print_list(head);*/
	/*for (int i = 0;i < 8;i++)
	{
		insert_T_list(head, i);
	}
	print_list(head);*/
	/*delete_val_list(head, 3);
	print_list(head);*/
	/*dele_T_list(head);
	print_list(head);
*/
	/*print_list(head);

	set_Empty( head);
	print_list(head);


	printf("haha\n");
*/


	/*初始化三个链表*/
	Node* La = init_Link_list();
	Node* Lb = init_Link_list();
	Node* Lc = init_Link_list();
	print_list(Lc);
	/*构造两个链表*/
	insert_T_list(La, 4);
	insert_T_list(La, 5);
	insert_T_list(La, 9);
	insert_T_list(La, 14);
	print_list(La);

	insert_T_list(Lb, 2);
	insert_T_list(Lb, 8);
	insert_T_list(Lb, 9);
	insert_T_list(Lb, 14);
	insert_T_list(Lb, 15);
	print_list(Lb);


	/*合成*/
	marge_list(La, Lb, Lc);
	print_list(Lc);

	/*释放空间*/
	//set_Empty(La);
	print_list(La);
	free(La);

	set_Empty(Lb);
	print_list(Lb);
	free(Lb);

	//set_Empty(Lc);
	print_list(Lc);
	free(Lc);





	//set_Empty(head);
	//print_list(head);
	//free(head);



	printf("haha\n");
	system("pause");
	return 0;
}



最后:将两个表合成后释放空间时的问题: 因为合并两个表时只是改变指针的指向,没有重新分配空间。 所以不能同时置空三个表,会造成空间的重复free.但是他们的 头节点还是要释放的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值