数据结构学习笔记-线性表链式存储(C语言实现)

时间:2021-05-05 10:14:42

写了两天,终于将线性表链式存储调通了,代码奉上:

#include <stdio.h>
#include <stdlib.h>
typedef int Eletype;
typedef struct Node{
Eletype date;
struct Node *next;
}Node;
typedef Node *LinkList;
//初始化链表 因为要改变链表数据,所以形参传递的是指向指针的指针,这种初始化方法叫做头插法(后插的在前边)还有尾插法
void init(LinkList *l,int size){
LinkList s;
(*l)=(LinkList)malloc(sizeof(Node));
(*l)->next=NULL;
for(int j=0;j<size;j++){
s=(LinkList)malloc(sizeof(Node));
s->date=rand()%100+1;
s->next=(*l)->next;
(*l)->next=s;
}
}
void initwei(LinkList *l,int size){
LinkList s,p;
(*l)=(LinkList)malloc(sizeof(Node));
p=*l;
for(int i=0;i<size;i++){
s=(LinkList)malloc(sizeof(Node));
s->date=rand()%100+1;
p->next=s;
p=s;//这里解释一下:链表p的next指向新结点,再把新结点付给链表,然后循环p的next再指向新结点
}
p->next=NULL;

}
//整表删除,这里必须要用声明q结点,因为q结点指向链表的第一个结点后边的结点,free方法释放的是整个结点
//包含指针域和数据域,如果将p结点直接释放,会造成只释放一个头结点,后边的结点就会找不到,导致他们并不会被释放掉
void cleanList(LinkList *l){
LinkList p,q;
p=(*l)->next;
while(p){
q=p->next;
free(p);
p=q;
}
(*l)->next=NULL;
}
//获取链表数据 不需要改变链表,所以形参传递的只是指针,从头开始遍历(不是从头节点开始,而是从第一有效数据开始)
int getEle(LinkList l,int index,Eletype *ele){
LinkList p=l->next;
int j=1;
while(p&&j<index){
p=p->next;
j++;
}
if(!p||j>index){
return 0;
}
*ele=p->date;
return 1;
}
//插入元素,循环这里说一下,这里只判断p是否存在即可,只要存在就往他后边插,这里的p是要插入的元素的前一个节点,也就 //是说如果插入的索引为1的话,p就从头节点开始遍历,所以p=*l
int insertEle(LinkList *l,int index,Eletype e){
LinkList p,s;
p=*l;
int i=1;
while(p&&i<index){
p=p->next;
i++;
}
if(!p||i>index){
return 0;
}
s=(LinkList)malloc(sizeof(Node));
s->date=e;
s->next=p->next;
p->next=s;
}
//删除元素,循环这里,因为是删除,通常链表的头结点都没有数据,需要从p的next开始判断,也就是从链表的第一个有效数据 //开始而不是从头节点开始
int deleteEle(LinkList *l,int index,Eletype *e){
LinkList p,s;
p=*l;
int i=1;
while(p->next&&i<index){
p=p->next;
i++;
}
if(!(p->next)||i>index){
return 0;
}
s=(LinkList)malloc(sizeof(Node));
s=p->next;
*e=s->date;
p->next=s->next;
free(s);
return 1;
}
void main(){
LinkList l;
Eletype e=0;
init(&l,6);
//initwei(&l,6);
for(int i=1;i<7;i++){
getEle(l,i,&e);
printf("%d ",e);
}
printf("\n");
insertEle(&l,2,20);
for(int i=1;i<8;i++){
getEle(l,i,&e);
printf("%d ",e);
}
printf("\n");
deleteEle(&l,1,&e);
printf("%d\n",e);
for(int i=1;i<7;i++){
getEle(l,i,&e);
printf("%d ",e);
}
printf("\n");
cleanList(&l);
getEle(l,5,&e);//这里因为链表被清空了,并没有取到值,所以该元素一直是上一次取到的值
printf("%d ",e);
}