【数据结构】单链表的代码
本文章代码部分参考王道《数据结构 考研复习指导》
单链表的结构定义
typedef struct Node{
//定义data用于存储值
int data;
//定义一个结构体指针,用来指向下一个节点
struct Node* next;
}Node,*linklist; //使用linlist作为*Node的别名,方便快捷调用结构体的指针
头插法建立单链表代码
//头插法,每次插入在上一个数据的前面,也就是先来的在后面,后来的在前面
//这里我们采用一个函数,获取我们要添加的链表
linklist Head_insert(linklist L)
{
//定义一个下新的节点,用于存放我们添加的数据
linklist s;
//给头节点分配一个初始空间
int x=0;
L = (linklist)malloc(sizeof(Node));
//默认头节点指向空
L->next = NULL;
//此处开始获取我们要插入的数值
printf("请输入数据:\n");
scanf("%d",&x);
//做了一个循环,来不断获取输入的数据
do{
//给新的节点分配空间,分配值
s = (linklist)malloc(sizeof(Node));
s->data = x;
//新节点指向的位置就是原来头节点指向的位置
s->next = L->next;
//头节点指向新来的节点
L->next = s;
//此处再次不断获取新数据,通过设置while判断的条件来停止
printf("请输入数据,-1结束:\n");
scanf("%d",&x);
}while(x!=-1);
printf("输入完成\n");
//最后返回我们新建立的链表
return L;
}
尾插法建立单链表代码
//尾插法就是新数据插入到已存在数据的后面,像排队一样往后站
linklist Tail_insert(linklist L)
{
//这里定义的s是新来的节点,r是我们用来指向最新节点的节点
linklist s;
linklist r;
int x=0;
L = (linklist)malloc(sizeof(Node));
//最初r指向L因为此时只有一个头节点L
r = L;
//同样的做循环用户不断输入数据,如果这样的写的话,最后结束的时候会把-1带到链表里面
do{
printf("请输入数据:\n");
scanf("%d",&x);
//给s分配空间,赋值,此时r指向s,因为s就是最新的节点
s = (linklist)malloc(sizeof(Node));
s->data = x;
r->next = s;
//r变成s,在下一次指向的时候,r可以带领新来的s找到最新的位置
r=s;
}while(x!=-1);
L->next = NULL;
return L;
}
单链表的插入代码
//此处的插入是插入在位置X之后,将X的指针指向新节点,新节点指向原来X指向的节点
linklist insert(linklist L)
{
//初始化一个临时的节点,作为此次遍历的节点,S就是新插入的节点
linklist temp = L->next;
linklist s;
//此处让用户输入插入的值和位置
int value,index;
printf("请输入插入数据的值:\n");
scanf("%d",&value);
printf("要插入到第几个数字的后面:\n");
scanf("%d",&index);
//分情况讨论,如果是插入最前面,那么需要改变头节点的指针
if(index==0){
s->data = value;
s->next = L->next;
L->next = s;
return L;
}
//不是插入头一个那么就按照此代码
else{
//做一个遍历,找到我们要插入位置的节点
int count = 0;
while(count!=index-1){
temp = temp->next;
count++;
}
//这里将temp的指针指向新节点,新节点指向原来temp指向的节点,顺序不能颠倒
s->data = value;
s->next = temp->next;
temp->next = s;
return L;
}
}
单链表的删除代码
//单链表的删除前面的操作都相同,在找到节点后,直接将前一个节点指向下一个节点的下一个节点,跳过那个节点,最后释放被跳过的节点
linklist delete_node(linklist L)
{
//和前者大同小异,这里改变了一些变量的名字
linklist temp = L->next;
linklist q;
int index;
printf("请输入要删除数据的位置");
scanf("%d",&index);
//同样做遍历,分情况,这里要注意计数的大小,上一个从0开始,这里从1开始,那么判断条件也是不一样的,如果不清楚的话在代码编写完后进行测试修改即可
int count = 1;
if(index==1)
{
L->next=temp->next;
}
else
{
while(count!=index-1){
temp = temp->next;
count++;
}
//被删除节点前一个节点指向的下一个节点,被删除节点的下一个
q = temp->next;
temp->next = q->next;
free(q);
}
return L;
}
单链表的计数代码
//单链表的计数只是把遍历代码拿出来,单独做的函数
//代码很简单,一个遍历计数
void count_list(linklist L)
{
linklist temp = L->next;
int count = 0;
while(temp!=NULL){
temp = temp->next;
count++;
}
printf("长度为%d",count);
打印单链表代码
void print_list(linklist L)
{
linklist temp = L->next;
while (temp != NULL) {
printf("%d\n", temp->data);
temp = temp->next;
}
printf("NULL\n");
}
函数调用测试代码示例
int main(int argc, char *argv[])
{
linklist L = NULL;
L=Head_insert(L);
print_list(L);
L=delete_node(L);
print_list(L);
count_list(L);
return 0;
}