线性表链式存储的循环单链表
- 循环链表从任意一点出发,可以访问全部节点。
- 一般为了便于操作,将链表的头指针变为尾指针,指向尾节点,链表的头节点则为尾指针的next。
代码收获
- 用尾指针进行操作虽然省下循环,但是插入删除等操作都需要移动尾指针导致必须传入尾指针的地址进行操作。
线性表归档
线性表顺序存储
线性表链式存储一——单链表
线性表链式存储二——循环链表
线性表链式存储三——双向链表
线性表链式存储四——静态链表
# include <stdio.h>
# include <stdlib.h>
typedef struct Node{
char data;
struct Node *next;
}Node,*Nodep;
//初始化,一开始尾指针指向尾节点即为头节点 ,自己指向自己
void Initiallist(Nodep* rear){
*rear = (Nodep)malloc(sizeof(Node));
(*rear)->next = *rear;
}
//插入数据 头插法,尾节要变为第一个节点位置,所以必须传地址,数据插入头节点之后
void InsertData(Nodep* prear){
printf("输入插入的数据,按$停止\n");
char c;
int flag=1;
Nodep head;
head = (*prear)->next;
while(flag){
c = getchar();
if (c!='$'){
Nodep newnode;
newnode = (Nodep)malloc(sizeof(Node));
newnode->data=c;
if(*prear==(*prear)->next){//第一个节点,不是第一个插入的节点尾指针不会等于头指针
*prear=newnode;//头插法导致需要把尾指针第一次插入时移向第一个插入的节点
newnode->next = head;
}else{
newnode->next=head->next;
}
head->next=newnode;
}else{
flag=0;
}
}
}
//尾插法 尾指针不断后移 要传地址
void TailInsert(Nodep* prear){
Nodep head;
head = (*prear)->next;
printf("\n输入插入的元素,按$结束\n");
int flag = 1;
while(flag){
char c;
c = getchar();
if(c!='$'){
Nodep newnode;
newnode = (Nodep)malloc(sizeof(Node));
newnode->data = c;
(*prear)->next=newnode;
newnode->next=head;
(*prear)=newnode;
}else{
flag=0;
}
}
}
//删除指定索引元素 若删除尾节点,则需要移动尾指针,所以传地址
int DeleteIndex(Nodep* prear){
int num;
printf("输入删除的元素索引\n");
scanf("%d",&num);
int k;
Nodep pp,pre;
if(num<=0){
printf("位置错误\n");
return 1;
}else{
pre = (*prear)->next;
for(k=1,pp=(*prear)->next->next;k<num;k++){
if (pp!=(*prear)->next){
pre = pp;
pp=pp->next;
}else{
printf("位置过大\n");
return 1;
}
}
if(pp==*prear){
*prear = pre;
pre->next=pp->next;
free(pp);
}else{
pre->next = pp->next;
free(pp);
}
}return 0;
}
//删除找到的第一个元素
int DeleteChar(Nodep* prear){
printf("输入要删除的元素\n");
char goal;
scanf("%c",&goal);
Nodep pp,pre;
pp = (*prear)->next->next;
pre=(*prear)->next;
while(goal!=pp->data){
if (pp==(*prear)->next){
printf("没找到数据\n");
return 1;
}else{
pre = pp;
pp =pp->next;
}
}
if(pp==(*prear)){
(*prear)=pre;
pre->next = pp->next;
free(pp);
}else{
pre->next=pp->next;
free(pp);
}return 0;
}
void Printlist(Nodep rear){//打印链表
Nodep pp;
Nodep head;
head = rear->next;
pp = head->next;
printf("链表为\n");
while(pp!=head){
printf("%c",pp->data);
pp=pp->next;
}
printf("\n");
}
void main(){
Nodep rear;
Initiallist(&rear);
InsertData(&rear);
getchar();
Printlist(rear);
TailInsert(&rear);
getchar();
Printlist(rear);
DeleteIndex(&rear);
getchar();
Printlist(rear);
DeleteChar(&rear);
getchar();
Printlist(rear);
}