#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);
}
c语言单链表的实现,包括链表的创建、插入、查询、删除、打印、长度计算
最新推荐文章于 2023-04-01 14:03:25 发布