#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define FLAG -1 //停止输入的标志
typedef struct Node
{
int data;
struct Node * next;
}LNode,*LinkList;
void show_List1(LinkList L);
void CreateLinkList1(LinkList L);
void CreateLinkList2(LinkList L);
LNode *GetLinkList(LinkList L,int i);
LNode *LocationLinkList(LinkList L,int x);
void InsertLinkList(LinkList L,int i,int x);
void DeleteLinkList(LinkList L,int i);
int LengthLinkList(LinkList L);
void reverse(LinkList L);
void DelLink(LinkList L,int min,int max);
LinkList MergeList(LinkList La,LinkList Lb);
void main()
{
//创建头指针指向头结点
LinkList L = (LNode *)malloc(sizeof(LNode));//La,Lb,Lc;
/*La = (LNode *)malloc(sizeof(LNode));
Lb = (LNode *)malloc(sizeof(LNode));
Lc = (LNode *)malloc(sizeof(LNode));*/
CreateLinkList2(L);
show_List1(L);
DelLink(L,4,8);
show_List1(L);
//La->next = Lb->next = Lc->next = NULL;
//CreateLinkList1(L);
/*printf("输入链表La:\n");
printf("输入链表Lb;\n");
CreateLinkList2(Lb);
printf("合并后的链表:\n");
Lc = MergeList(La,Lb);
show_List1(Lc);*/
//printf("\n%p",GetLinkList(L,2));//输出结点指针地址
//printf("\n%p",LocationLinkList(L,2));//
/* InsertLinkList(L,2,99);
show_List1(L);
DeleteLinkList(L,5);
show_List1(L);
printf("%d",LengthLinkList(L));*/
/*reverse(L);
printf("倒置后的链表:\n");
show_List1(L);*/
/*DelLink(L,3,7);
printf("删除后的链表:\n");
show_List1(L);*/
}
void show_List1(LinkList L)
{
LinkList p = L->next;
printf("%d",p->data);
p = p ->next;
while(p != NULL)
{
printf("->%d",p->data);
p = p->next;
}
printf("\n");
}
void CreateLinkList1(LinkList L) //头插法 输出的是输入的逆序
{
LinkList s;
int x;
scanf("%d",&x);
while(x != FLAG)
{
/*s = L;
s->data = x;
L = (LNode *)malloc(sizeof(LNode));
L->next = s;*/
s = (LNode *)malloc(sizeof(LNode));
s->data = x;
s->next = L->next;
L->next = s;
scanf("%d",&x);
}
}
void CreateLinkList2(LinkList L) //尾插法 输出是输入的正序
{
LinkList s,r;
int x;
scanf("%d",&x);
r = L; //没写闪退
while(x != FLAG)
{
s = (LNode *)malloc(sizeof(LNode));
s->data = x;
//r->next = s;
//s->next = r->next; 出错误的原因是r->next中已经是新节点的地址了,
//再把新节点地址赋值给它的指针域,会导致自己不断的指自己 不断 33333
//不妨先把r->next也就是NULL赋给新节点指针域,再将上一个指向新节点,这样就没问题了!
//s->next = r->next; //第一种写法
r->next = s;
r = s;
scanf("%d",&x);
}
r->next = NULL;//第二种写法 先不管最后一个节点,最后再置为NULL
}
LNode *GetLinkList(LinkList L,int i)//按位置查找
{
LinkList p;
int j = 0;
p = L;
while(p != NULL && j < i)
{
p = p->next;
j++;
}
return p;
}
LNode *LocationLinkList(LinkList L,int x) //按元素查找
{
LinkList p;
p = L->next;
while(p != NULL && p->data != x)
{
p = p->next;
}
return p;
}
void InsertLinkList(LinkList L,int i,int x)
{
LinkList p,s;
p = GetLinkList(L,i-1);
if(p == NULL)
{
printf("插入失败!");
exit(1);//0 -1 1 一般0是正常退出 其他是异常退出
}
else
{
s = (LNode*)malloc(sizeof(LNode));
s->data = x;
s->next = p->next;
p->next = s;
}
}
void DeleteLinkList(LinkList L,int i)//删除第i个位置 p需要指向第i-1个位置
{
LinkList q,p;
p = GetLinkList(L,i-1);
if(p == NULL)
{
printf("删除失败!");
exit(1);
}
else
{
if(p->next == NULL)
{
printf("删除失败!");
exit(1);
}
else
{
q = p->next;
p->next = p->next->next;
free(q);
}
}
}
int LengthLinkList(LinkList L)
{
int len = 0;
LinkList p = L;
while(p->next)
{
len++;
p = p->next;
}
return len;
}
void reverse(LinkList L)
{
//节点指针p q
//先把p指向首节点,再将头结点的指针域置为空 这样就出现一个p指向首节点的链表
//q指向与p相同的结点 然后p后移
//头结点的指针域中永远存放的是上一个结点的地址
//
/*LinkList p,q;
p = L->next;
L->next = NULL;
while(p)
{
q = p;//先将p赋值给q
p = p->next; // p后移
q->next = L->next; //
L->next = q;
}*/
//设置了两个游标 p主要负责查看是否是最后一个元素 并且 将后面的元素串联起来
LinkList p,q;
p = L->next; //记录下后面的所有元素
L->next = NULL;//方便设置第一个元素的指针域为0
while(p) // 是p不是p->next的原因 在于p->next会使最后一个元素无法倒置
{
q = p;
p = p->next;//这一步必须在 第三步的前面 否则将会失去后面的所有元素
q->next = L->next; //头结点中的指针域永远记录上一个元素的地址
L->next = q;//q当前所指元素指向上一个元素后 头结点记录下当前节点地址
}
}
void DelLink(LinkList L,int min,int max)
{
LinkList p,q,s;
p = L->next;
while((p != NULL) && (p->data <= min))
{
q = p;
p = p->next;
}
while((p != NULL) && (p->data < max))
{
s = p;
p = p->next;
//删除结点
//q->next = p;
free(s);
}
q->next = p; //
}
LinkList MergeList(LinkList La,LinkList Lb)
{
LinkList p,q,r,Lc;
p = La->next;
q = Lb->next;
r = Lc = Lb;
while(q&&p)
{
//p或者q中数据域小的那个应当让上一个结点指向
//并且应当把r指向小的那个结点
//进行完上叙操作后,数据域小的那个应当将p或者q后移
if(p->data >= q->data)
{
r->next = q;
r = r->next;
q = q->next;
}
else
{
r->next = p;
r = r->next;
p = p->next;
}
}
if(q)
{
//说明后面还有
r->next = q;
}
else
{
r->next = p;
}
free(La);
return Lc;
}
C语言实现数据结构单链表的相关操作
最新推荐文章于 2022-08-23 11:09:12 发布