代码收获:
- 循环链表一般新建一个指针跟着循环移动,如果需要插入或者删除操作,还需要新建个指针指向循环时候的前一个结点。
- getchar()最后敲的回车会卡进缓存里,需要继续用一次getchar()把回车给吃了。
- 初始化如果不想返回指针的话使用二级指针,函数内等于一步分配空间的操作给二级的一级指针明确了地址指向。
# include <stdio.h>
# include <stdlib.h>
typedef struct Node{
char data;
struct Node *next;
}Node,*Nodep;
void Initial(Nodep *L){//初始化
*L=(Nodep)malloc(sizeof(Node));
(*L)->next = NULL;
}
void TailInsert(Nodep L){//尾插法
printf("请输入要插入的数据,$结束\n");
char c;
int flag;
flag = 1;
while(flag){
c=getchar();
if(c!='$'){
Nodep pNode,tail,pre;
pNode = (Nodep)malloc(sizeof(Node));
pNode->data = c;
pNode->next = NULL;
tail=L->next;
pre =L;
while(tail!=NULL){
pre = tail;
tail = pre->next;
}//pre为尾
pre->next=pNode;
}
else{
flag=0;
}
}
}
void HeadInsert(Nodep L){//头插法
printf("请输入要插入的数据,$结束\n");
Nodep pNode;
char c;
int flag;
flag = 1;
while(flag){
c=getchar();
if(c!='$'){
pNode=(Nodep)malloc(sizeof(Node));
pNode->data=c;
pNode->next=L->next;
L->next=pNode;
}
else{
flag=0;
}
}
}
int DeleteNode(Nodep L,char s){//删除第一个找到的指定节点
Nodep tail,pre;
tail=L->next;
pre = L;
if(tail!=NULL){
while(tail->next!=NULL){
if(tail->data==s){
pre->next = tail->next;
free(tail);
return 0;
}
else{
pre = tail;
tail=tail->next;
}
}
}
printf("未找到删除数据\n");
return -1;
}
int DeleteIndex(Nodep L,int k){//删除指定索引
int num;
Nodep tail,pre;
num=1;
tail=L->next;
pre = L;
if(tail!=NULL){
do{
if(num==k){
pre->next=tail->next;
free(tail);
return 0;
}
else{
pre =tail;
tail=tail->next;
num++;
}
}while(tail->next!=NULL);
}
printf("未找到删除数据\n");
return -1;
}
void Printlist(Nodep L){//打印链表
Nodep pp;
pp = L->next;
printf("链表为\n");
while(pp!=NULL){
printf("%c",pp->data);
pp=pp->next;
}
printf("\n");
}
int Length(Nodep L){//求链表长度
int num;
Nodep tail;
num=0;
for(tail=L;tail->next!=NULL;tail=tail->next){
num++;
}
return num;
}
void main(){
Nodep L;
char s='s';//删除节点s
Initial(&L);
TailInsert(L);
getchar();//吃掉回车
HeadInsert(L);
getchar();//吃掉最后的回车
Printlist(L);
DeleteNode(L,s);
Printlist(L);
int k=3;//要删除的索引
DeleteIndex(L,k);
Printlist(L);
int num;
num= Length(L);
printf("长度为%d",num);
}