本文主要介绍利用快慢指针访问中间节点的方法,至于链表的其它操作,之前已经写过,这里不多作介绍
#include<stdio.h>
#include<stdlib.h>
typedef struct student{
int score;
char name[50];
}student_t;
typedef struct listnode{
student_t data;
struct listnode*next;
struct listnode*prev;
}student_node_t,*student_list_t;
void InputData(student_node_t*head);//往链表中传入数据
void PrintMidData(student_node_t* head,student_node_t* temp);//输出中间节点的数据
void PrintAllInfo(student_node_t* head);//输出所有数据信息
int main(){
student_node_t*head,* temp;
head=(student_list_t)malloc(sizeof(student_node_t));
head->next=head->prev=head;
char ch;
do{
printf("\n-----------------------------------------------------------------------------------\n");
printf("\n");
printf("\t\t\t[A].添加数据");
printf("\n\n\t\t\t[P].显示学生数据");//默认按照初始输入的顺序打印
printf("\n\n\t\t\t[M].输出中间结点的数据");
printf("\n\n\t\t\t[E].退出");
printf("\n\n-----------------------------------------------------------------------------------");
printf("\n\n请输入选项:");
ch=getchar();
switch(ch){
case 'a':
case 'A':
InputData(head);//往链表中先存数据
break;
case 'p':
case 'P':
PrintAllInfo(head);
while('\n'!=getchar());
break;
case 'M':
case 'm':
PrintMidData(head,temp);
while('\n'!=getchar());
break;
}
}while(ch!='e'&&ch!='E');
return 0;
}
void PrintMidData(student_node_t* head,student_node_t* temp){//用快慢指针查询中间节点数据
student_node_t* fast;
temp=(student_node_t*)malloc(sizeof(student_node_t));
temp=head->next;//将慢指针置于第二个节点处
fast=temp->next;//将快指针置于慢指针的下一个结点处
int flag;
while(1){
if(fast==head){
flag=0;//若快指针最后能指向头结点,说明有奇数个数据节点
break;
}
if(fast==head->prev){
flag==1;
break;
}//若快指针最后能指向尾部节点,说明有偶数个数据节点
temp=temp->next;
fast=fast->next->next;
}
if(flag==0){
printf("中间学生数据如下:\n\n");
printf("\n------------------------------------------------------------\n");
printf("\n\t\t%-20s%-20s\n","Name","Score");
printf("\n\n\t\t%-20s%-20d\n",temp->data.name,temp->data.score);
}
else{
printf("中间节点的两名学生的数据如下:\n\n");
printf("---------------------------------------------------------------\n");
printf("\n\t\t%-20s%-20s","Name","Score");
printf("\n\n\t\t%-20s%-20d",temp->data.name,temp->data.score);
printf("\n\n\t\t%-20s%-20d",temp->next->data.name,temp->next->data.score);
}
}
void InputData(student_node_t* head){//输入学生相关数据,用尾插法
student_node_t* temp=NULL;
char choice;
while(1){
temp=(student_list_t)malloc(sizeof(student_node_t));
printf("\nInput score:");
scanf("%d",&temp->data.score);
while('\n'!=getchar());
printf("\nInput name:");
scanf("%[^\n]",temp->data.name);
temp->next=head;
head->prev->next=temp;
temp->prev=head->prev;
head->prev=temp;
printf("\n[C].Continue [E].Exit\n\n");
while('\n'!=getchar());//清空缓冲区,暂时还不清楚Linux里专门用来清空缓冲区的方法
printf("\n\nInput you choice:");
choice=getchar();
if(choice=='E'||choice=='e')break;
}
while('\n'!=getchar());
}
void PrintAllInfo(student_node_t*head){//显示出所有数据
if(head->next==head){
printf("\n还没有存数据!\n");
return ;
}
student_node_t *temp;
temp=head->next;
printf("\n\nHere is all student information:\n\n");
printf("-------------------------------------------------------\n\n");
printf("\n\t\t%-20s%-20s","Name","Score");
while(temp!=head){
printf("\n\n\t\t%-20s",temp->data.name);
printf("%-20d",temp->data.score);
temp=temp->next;
}
}