c语言单链表的实现,包括链表的创建、插入、查询、删除、打印、长度计算

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

typedef struct node{
	char data;
	struct node *next;
}LINKLIST;

//  链表初始化操作,返回一个空链表 
LINKLIST *INITLIST()
{
	LINKLIST *head;
	head = (LINKLIST*)malloc(sizeof(LINKLIST));
	head->next = NULL;
	return head;
} 
//  链表的建立1(尾插入法建立链表,就是从链表的直接尾部添加数据用指针连起来)
LINKLIST *rCreate()
{
	LINKLIST *head,*last,*p;
	char ch;
	head = (LINKLIST*)malloc(sizeof(LINKLIST));
	head->next = NULL;
	last = head;
	printf("请输入链表数值(尾插入法),@符号终止输入:\n");
	while((ch = getchar()) != '@')
	{
//		接收到@字符时跳出循环 
		p = (LINKLIST*)malloc(sizeof(LINKLIST));
		p->data	= ch;
		last->next = p;
		last = p;//重新对last赋值 
		p->next = NULL;//到尾了 
	} 
	return head;
}
//   链表的建立2(头插入法建立链表,每一个数据都是直接插入在head的后面,然后将后面的数据后移,有点像堆栈,先进后出) 
LINKLIST *hCreate()
{
	LINKLIST *head,*p;
	char ch;
	head = (LINKLIST*)malloc(sizeof(LINKLIST));
	head->next = NULL;
	printf("请输入链表数值(头插入法),@符号终止输入:\n");
	while((ch = getchar()) != '@')
	{
		p = (LINKLIST*)malloc(sizeof(LINKLIST));
		p->data = ch;
		p->next = head->next;//让head第一次指向的元素向后移动一个单位 
		head->next = p;//head指向的下一个就是p 
	}
	return head;
} 
//  计算链表的长度
int LENGTH(LINKLIST *head)
{
//	注意这个地方,传入的head的是结构指针
//  改变结构指针里面东西是不会像原来改变整数一样改变原来的head内容的(这里的p有点像是局部变量,不会改变head) 
	int i = 0;
	LINKLIST *p = head;
	while(p = p->next)
		i++;
	return i;
} 
//   寻找链表里的第n个节点(n>=1),其实就是获得第n个之后的链表 
LINKLIST *GET(LINKLIST *head,int n)
{
	LINKLIST *p = head;
	int i = 1;
	while(i<=n&&p)
	{
		p = p->next;
		i++;	
	}	
	return p;
} 
//    根据用户输入的节点data值寻找节点
LINKLIST *LOCATE(LINKLIST *head,char data)
{
	LINKLIST *p = head->next;
	while(p&&(p->data!=data))
		p = p->next;
	return p;//这里的p最终指向的已经是NULL了,没找到不用赋值直接返回 
} 
//   插入操作,输入一个n,在n-1位置插入(类似于数组的插入,但是此处n>=2) 
void INSERT(LINKLIST *head,int n,char data)
{
	LINKLIST *inserted,*p;
	inserted = (LINKLIST*)malloc(sizeof(LINKLIST));//给要插入的节点malloc 
	inserted->next = NULL;
	inserted->data = data;
	p = GET(head,n-1);//查找插入元素的前一位数 
	if(p)
	{
//		找到了该节点,开始插入
		inserted->next = p->next;
		p->next = inserted;
		printf("insert successful!\n");
	}else{
		printf("insert fail\n");
	}
} 

//      删除第n个元素
void DELETE(LINKLIST *head,int n)
{
	LINKLIST *p,*q;
	p = GET(head,n-1);//获取到要删除的前一位元素 
	if(p&&p->next)
	{
		q = p->next;
		p->next = q->next;
		free(q);
		printf("delete success\n");
	}else{
		printf("delete fail\n");
	}
}
//  判断链表是否为空
int isEmpty(LINKLIST *head)
{
	if(head->next)
		return 1;
	return 0;
} 
//  单链表的打印
void listPrint(LINKLIST *head) 
{
	LINKLIST *p;
	p = head->next;
	if(!p){
		printf("链表有误!请检查后再打印\n");
		return; 
	}
	while(p){
		printf("%c->",p->data);
		p = p->next;
	}
	printf("\n");
}
//   合并有序链表 (由大到小排序),LA,LC都必须是从大到小排序的,如LA = [1,3,5],LB = [2,4,6] 
void MergeList(LINKLIST *LA,LINKLIST *LB,LINKLIST **LC){
	LINKLIST *pa = LA->next;
	LINKLIST *pb = LB->next;
	LINKLIST *pc;//注意这里的pc是局部变量,所以传入的LC必须是指针的指针形式,否则是在外面得不到值的 
	pc = *LC = LA;
	while(pa&&pb)
	{
		if(pa->data<=pb->data)
		{
			pc->next = pa;//让pc的指针域指向pa 
			pc = pa;//移动外部pc指针 
			pa = pa->next;//是pa向自己的链表移动一个单位 
		}else{
			pc->next = pb;
			pc = pb;
			pb = pb->next;
		}
	}
//	有一个链表循环完毕,加入剩余链表的内容
	pc->next = pa ? pa : pb;
	free(LB);//释放LB区域 
}
int main()
{
//	LINKLIST *list = rCreate();
	LINKLIST *list = INITLIST();
//	LINKLIST *list = hCreate();
//	LINKLIST *get = GET(list,1);
//	LINKLIST *locate = LOCATE(list,'2');
//	int emp = isEmpty(list);
//	DELETE(list,4);
//	INSERT(list,3,'i');
	int len = LENGTH(list);
	listPrint(list);
//	printf("%d",emp);
	printf("length=%d",len);
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页