双向链表的初始化插入与删除
代码收获
- 双向链表删除结点需要注意要删除最后一个结点和不是最后一个结点分类讨论。
- 插入和删除时注意修改上一个结点里指向下一个结点的指针与下一个结点里指向上一个结点的指针。
线性表归档
线性表顺序存储
线性表链式存储一——单链表
线性表链式存储二——循环链表
线性表链式存储三——双向链表
线性表链式存储四——静态链表
#include <stdio.h>
#include <stdlib.h>
//双向链表,一个结构里除了数据外有2个指针,一个指向前一个节点,一个指向后一个节点
typedef struct biprolist{
struct biprolist *head;
char data;
struct biprolist *tail;
}Node,*Nodep;
//初始化链表,有一个头结点,让其head和tail指向null
void InitialList(Nodep *L){
*L = (Nodep)malloc(sizeof(Node));
(*L)->head = NULL;
(*L)->tail = NULL;
}
//头插法
void InsertList(Nodep L){
printf("请输入插入的数据,$结束\n");
int flag = 1;
while(flag){
char c;
c = getchar();
if(c!='$'){
Nodep newnode;
newnode = (Nodep)malloc(sizeof(Node));
newnode->data=c;
newnode->head=L;
newnode->tail=L->tail;
L->tail = newnode;
if(newnode->tail!=NULL)
{newnode->tail->head = newnode;}
}else{
flag=0;
}
}
getchar();//吃回车
}
//尾插法
void Inserttail(Nodep L){
printf("请输入要插入的数据,$结束\n");
int flag = 1;
Nodep movep;//找到让其始终指向尾巴
movep=L;
while(movep->tail!=NULL){
movep = movep->tail;
}
while(flag){
char c;
c = getchar();
if(c!='$'){
Nodep newnode;
newnode=(Nodep)malloc(sizeof(Node));
newnode->data=c;
newnode->head=movep;
newnode->tail=NULL;
movep->tail=newnode;
movep = newnode;
}else{
flag=0;
}
}
getchar();
}
void Printlist(Nodep L){
Nodep move;
move = L;
printf("链表为\n");
while(move->tail!=NULL){
move=move->tail;
printf("%c",move->data);
}
printf("\n倒着为\n");
while(move->head!=NULL){
printf("%c",move->data);
move= move->head;
}
}
//删除节点
int DeleteNode(Nodep L){
int flag =1;
while(flag){
int num;
Nodep move=L;
printf("请输入要删除的节点索引(从0开始)\n");
scanf("%d",&num);
int i;
for(i=0;i<=num;i++){
if(move->tail==NULL){
printf("索引错误\n");
return 1;
}else{move=move->tail;
}
}if(move->tail==NULL){
move->head->tail=NULL;
free(move);
}else{
move->head->tail =move->tail;
move->tail->head = move->head;
free(move);}
Printlist(L);
printf("是否继续(y/n)\n");
getchar();
char f;
f= getchar();
if(f=='n'){
flag = 0;
}
} return 0;
}
void main(){
Nodep L;
InitialList(&L);
InsertList(L);
Printlist(L);
Inserttail(L);
Printlist(L);
DeleteNode(L);
}