使用快慢指针访问(双向)链表中间节点的数据(有头结点的双向链表)

本文主要介绍利用快慢指针访问中间节点的方法,至于链表的其它操作,之前已经写过,这里不多作介绍

#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;
    }
}

有头结点的单向链表中间节点数据快慢指针查询方法:通过快慢指针遍历链表,先将慢指针指向头结点的下一个节点,将快指针置于慢指针所指节点的下一个节点,结束遍历的条件:

(1).fast->next=NULL;说明含数据节点个数为偶数,有两个中间节点,输出慢指针所指数据时应输出两个中间节点的数据,一个为慢指针所指数据域,一个为慢指针下一个节点的数据,二者都为中间节点
(2).(fast->next)->next=NULL;说明有奇数个数据节点,慢指针所指向的数据域就是中间节点的数据

猜你喜欢

转载自blog.csdn.net/qq_41681241/article/details/81054622