数据结构学习——循环链表的使用

2023-11-04

一、循环链表的介绍

        循环链表是一种特殊类型的链表,其中链表中的最后一个节点指向链表中的第一个节点,形成循环的结构。与普通链表相比,循环链表可以在链表中的任何位置进行遍历,并且可以方便地实现循环操作。在循环链表中,每个节点通常包含一个数据元素和一个指向下一个节点的指针。链表中的最后一个节点的指针指向第一个节点,形成闭环。

二、循环链表的创建以及初始化

        进行链表初始化时,以用户键盘输入“0” 作为结束标志,通过链表初始化函数,可直接规定了链表长度。

typedef struct Node{
    int data;
    struct Node* next;
}Node;

//结构体定义

void Node_init(Node **head){
    int item;
    Node* target;
    printf("输入节点的值,输入0完成初始化\n");
    while(1){
        scanf("%d",&item); //item为从键盘输入插入节点的值
        if( item==0 )return;
        if((*head)==NULL){ //当循环链表头节点为空的时候
            *head = (Node *)malloc(sizeof(struct Node));
            if(!(*head))exit(0);
            (*head)->data = item;
            (*head)->next = *head;
        }
        else{
            //找到最后一个节点进行尾插
            for(target = *head; target->next != *head; target = target->next);
            Node* temp = (Node *)malloc(sizeof(struct Node));
            if(!temp)exit(0);
            temp->data = item;
            temp->next = *head;
            target->next = temp;
        }
    }
}

三、菜单栏样式设置

        本程序做了一个菜单选择页面,提供给用户从键盘输入选择不同的操作。效果如图:

 代码部分:

void Style_set(){
    int j,height = 5,width = 60;
    for(j = 0; j < width; j++)printf("*");
    printf("\n*");
    for(j = 0; j < (width - 20)/2 ; j++)printf(" ");
    printf("请输入要进行的操作选项:");
    for(j = 0; j < (width - 30)/2 ; j++)printf(" ");
    printf("*\n");

    printf("*");
    for(j = 0; j < (width - 20)/2; j++)printf(" ");
    printf("(1).初始化链表");
    for(j = 0; j < (width - 12)/2; j++)printf(" ");
    printf("*\n");

    printf("*");
    for(j = 0; j < (width - 20)/2; j++)printf(" ");
    printf("(2).插入新节点");
    for(j = 0; j < (width - 12)/2; j++)printf(" ");
    printf("*\n");
    
    printf("*");
    for(j = 0; j < (width - 20)/2; j++)printf(" ");
    printf("(3).删除指定结点");
    for(j = 0; j < (width - 16)/2; j++)printf(" ");
    printf("*\n");

    printf("*");
    for(j = 0; j < (width - 20)/2; j++)printf(" ");
    printf("(4).查找指定结点");
    for(j = 0; j < (width - 16)/2; j++)printf(" ");
    printf("*\n");

    printf("*");
    for(j = 0; j < (width - 20)/2; j++)printf(" ");
    printf("(5).遍历链表");
    for(j = 0; j < (width - 8)/2; j++)printf(" ");
    printf("*\n");

    for(j = 0; j < width; j++)printf("*");
    printf("\n");
}

四、链表插入节点

        这里写的函数可以指定链表位置进行插入。

void insert_node( Node** head,int i){
    int j = 1;
    Node* target = *head;
    int item;
    printf("请输入插入结点的值\n");
    scanf("%d",&item);
    if(!item) exit(0);
    if(i == 1){
        struct Node* temp = (Node*)malloc(sizeof(struct Node));
        temp->data = item;
        for( ;target->next != *head; target = target->next);
        temp->next = *head;
        target->next = temp;
        *head = temp;
    }
    else{
        if(!item)exit(0);
        target = *head;
        for( ; j < (i-1); j++)
        target = target->next;
        Node* temp = (Node*)malloc(sizeof(struct Node));
        temp->data = item;
        Node* p = target->next;
        target->next = temp;
        temp->next = p;
    }
}

五、删除一个节点

        与指定位置插入节点类似,在删除节点时同样也能够指定位置,通过找到指定位置的前驱节点,从前驱节点断开并将其next指向删除节点的下一个节点,最后在释放掉删除节点的内存。

void delete_node(Node **head,int i){
    Node* target;
    int j = 1;
    if( i==1 ){//删除第一个结点
    for(target = *head ; target != *head; target = target->next);
    Node* temp = *head;
    *head = (*head)->next;
    target->next = *head;
    free(temp);
    }
    else{
        target = *head;
        for( ; j < (i-1); j++)
        target = target->next;//寻找删除位置结点的前驱结点
        Node* temp = target->next;
        target->next = temp->next;
        free(temp);
    }
}

六、按值查找对链表搜索

        这里只传递结构体,不对其修改,因此不需要用指针指向结构体,将查找的值从链表的头节点开始逐个比较,当比较到最后一个节点依然没有找到时就提示找不到该元素,若找到则返回该节点所在的位置。

int Search_Node(Node* head, int value){
    Node* target;
    int i = 1;
    for(target = head; target->data != value && target->next != head; ++i)
    target = target->next;
    if(target->next = head) //不存在该元素
    return 0;
    else  
    return i;
}

七、循环链表的遍历

        与单链表的遍历仅多了对尾节点的下一节点是否是头节点的判断。

void PrintOut_Link(Node *head){
    Node* temp = head;
    printf("***********链表中的元素为************\n");
    do
    {
        printf("%4d ",temp->data);
    } while ((temp = temp->next) != head);
    printf("\n");       
}

八、主函数以及全部代码

void main(){
    char opp;
    int pos;
    Node* head = NULL;
    Style_set();
    while( opp != '0'){
        scanf("%c",&opp);
        switch(opp){
            case '1' :
                Node_init(&head);printf("\n");
                PrintOut_Link(head);
                Style_set();
                break;
                break;
            case '2' :
                printf("请输入插入结点的位置\n");
                scanf("%d",&pos);
                insert_node(&head,pos);
                printf("在%d处插入值后:  \n",pos);
                PrintOut_Link(head);
                printf("\n");
                Style_set();
                break;//单个break 
            case '3' :
                printf("请输入要删除结点的位置\n");
                scanf("%d",&pos);
                delete_node(&head,pos);
                printf("在%d处值删除后:  \n",pos);
                PrintOut_Link(head);
                printf("\n");
                Style_set();
                break;
            case '4' :
                printf("请输入要查找结点的值\n");
                scanf("%d",&pos);
                pos = Search_Node(head,pos);
                if(pos == 0)printf("查无此值\n");
                else printf("所查找值的位置是:  %d \n",pos);
                PrintOut_Link(head);
                printf("\n");
                Style_set();
                break;
            case '5' :
                PrintOut_Link(head);
                printf("\n");
                Style_set();
                break;
            case '0' :
                exit(0);
        }   
    }
}

全部代码:

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

typedef struct Node{
    int data;
    struct Node* next;
}Node;

void insert_node(Node **head,int i);
void Style_set();
void Node_init(Node **head);
void delete_node(Node **head,int i);
int Search_Node(Node* head, int value);
void PrintOut_Link(Node *head);

void main(){
    char opp;
    int pos;
    Node* head = NULL;
    Style_set();
    while( opp != '0'){
        scanf("%c",&opp);
        switch(opp){
            case '1' :
                Node_init(&head);printf("\n");
                PrintOut_Link(head);
                Style_set();
                break;
                break;
            case '2' :
                printf("请输入插入结点的位置\n");
                scanf("%d",&pos);
                insert_node(&head,pos);
                printf("在%d处插入值后:  \n",pos);
                PrintOut_Link(head);
                printf("\n");
                Style_set();
                break;//单个break 
            case '3' :
                printf("请输入要删除结点的位置\n");
                scanf("%d",&pos);
                delete_node(&head,pos);
                printf("在%d处值删除后:  \n",pos);
                PrintOut_Link(head);
                printf("\n");
                Style_set();
                break;
            case '4' :
                printf("请输入要查找结点的值\n");
                scanf("%d",&pos);
                pos = Search_Node(head,pos);
                if(pos == 0)printf("查无此值\n");
                else printf("所查找值的位置是:  %d \n",pos);
                PrintOut_Link(head);
                printf("\n");
                Style_set();
                break;
            case '5' :
                PrintOut_Link(head);
                printf("\n");
                Style_set();
                break;
            case '0' :
                exit(0);
        }   
    }
}

void Node_init(Node **head){
    int item;
    Node* target;
    printf("输入节点的值,输入0完成初始化\n");
    while(1){
        scanf("%d",&item);
        fflush(stdout);
        if( item==0 )return;
        if((*head)==NULL){
            *head = (Node *)malloc(sizeof(struct Node));
            if(!(*head))exit(0);
            (*head)->data = item;
            (*head)->next = *head;
        }
        else{
            for(target = *head; target->next != *head; target = target->next);
            Node* temp = (Node *)malloc(sizeof(struct Node));
            if(!temp)exit(0);
            temp->data = item;
            temp->next = *head;
            target->next = temp;
        }
    }
}

void Style_set(){
    int j,height = 5,width = 60;
    for(j = 0; j < width; j++)printf("*");
    printf("\n*");
    for(j = 0; j < (width - 20)/2 ; j++)printf(" ");
    printf("请输入要进行的操作选项:");
    for(j = 0; j < (width - 30)/2 ; j++)printf(" ");
    printf("*\n");

    printf("*");
    for(j = 0; j < (width - 20)/2; j++)printf(" ");
    printf("(1).初始化链表");
    for(j = 0; j < (width - 12)/2; j++)printf(" ");
    printf("*\n");

    printf("*");
    for(j = 0; j < (width - 20)/2; j++)printf(" ");
    printf("(2).插入新节点");
    for(j = 0; j < (width - 12)/2; j++)printf(" ");
    printf("*\n");
    
    printf("*");
    for(j = 0; j < (width - 20)/2; j++)printf(" ");
    printf("(3).删除指定结点");
    for(j = 0; j < (width - 16)/2; j++)printf(" ");
    printf("*\n");

    printf("*");
    for(j = 0; j < (width - 20)/2; j++)printf(" ");
    printf("(4).查找指定结点");
    for(j = 0; j < (width - 16)/2; j++)printf(" ");
    printf("*\n");

    printf("*");
    for(j = 0; j < (width - 20)/2; j++)printf(" ");
    printf("(5).遍历链表");
    for(j = 0; j < (width - 8)/2; j++)printf(" ");
    printf("*\n");

    for(j = 0; j < width; j++)printf("*");
    printf("\n");
}

void insert_node( Node** head,int i){
    int j = 1;
    Node* target = *head;
    int item;
    printf("请输入插入结点的值\n");
    scanf("%d",&item);
    if(!item) exit(0);
    if(i == 1){
        struct Node* temp = (Node*)malloc(sizeof(struct Node));
        temp->data = item;
        for( ;target->next != *head; target = target->next);
        temp->next = *head;
        target->next = temp;
        *head = temp;
    }
    else{
        if(!item)exit(0);
        target = *head;
        for( ; j < (i-1); j++)
        target = target->next;
        Node* temp = (Node*)malloc(sizeof(struct Node));
        temp->data = item;
        Node* p = target->next;
        target->next = temp;
        temp->next = p;
    }
}

void delete_node(Node **head,int i){
    Node* target;
    int j = 1;
    if( i==1 ){//删除第一个结点
    for(target = *head ; target != *head; target = target->next);
    Node* temp = *head;
    *head = (*head)->next;
    target->next = *head;
    free(temp);
    }
    else{
        target = *head;
        for( ; j < (i-1); j++)
        target = target->next;//寻找删除位置结点的前驱结点
        Node* temp = target->next;
        target->next = temp->next;
        free(temp);
    }
}

int Search_Node(Node* head, int value){
    Node* target;
    int i = 1;
    for(target = head; target->data != value && target->next != head; ++i)
    target = target->next;
    if(target->next = head) //不存在该元素
    return 0;
    else  
    return i;
}

void PrintOut_Link(Node *head){
    Node* temp = head;
    printf("***********链表中的元素为************\n");
    do
    {
        printf("%4d ",temp->data);
    } while ((temp = temp->next) != head);
    printf("\n");       
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构学习——循环链表的使用 的相关文章

  • 考研复试数据库原理课后习题(十三)——大数据管理

    大数据管理 1 什么是大数据 大数据有何特征 大数据是指无法在可容忍的时间内用现有IT技术和软硬件工具对其进行感知 获取 管理 处理和服务的数据集合 大数据的基本特征如下 大数据的首要特征是数据量巨大 而且在持续 急剧地膨胀 大数据异构的数
  • 《疯狂java讲义》读书笔记(七):多线程

    疯狂java讲义 读书笔记 七 多线程 1 线程和进程 这两个概念必须得区分 之前学操作系统的时候我老给弄混了 进程的三种基本状态 1 运行态 running 当进程得到处理机 其执行程序正在处理机上运行时的状态称为运行状态 在单CPU系统

随机推荐

  • 为什么React不允许直接修改state

    React强烈不建议直接修改state 究其原因可以从两方面进行阐述 性能问题 React提倡不可变性 通过setstate 修改state实际上是创建了一个副本用来代替原来的state 这与直接修改原数据有着本质的区别 其他框架类似ang
  • /etc/sysconfig/network中的NOZEROCONF配置(多出169.254.0.0网段的路由)

    1 问题 发现多了从169 254 0 0网段出去的eth0 但eth0配置的IP是192 168 1 3 2 解决 169 254 0 0原是windows下的主机dhcp获取ip失效时 预设的一个ip地址段 linux照搬过来 169
  • [数值计算-2]:数值计算算法好坏的判断标准

    作者主页 文火冰糖的硅基工坊 https blog csdn net HiWangWenBing 本文网址 https blog csdn net HiWangWenBing article details 119776181 目录 1 案
  • debian 系统无法使用 systemctl

    systemctl status sshd 报错如下 Failed to get D Bus connection Unknown error 1 解决方法 apt install systemd sysv reboot
  • Python爬虫学习笔记(十一)————scrapy shell

    目录 1 什么是scrapy shell 2 安装ipython 安装 3 应用 1 scrapy shell www baidu com 2 scrapy shell http www baidu com 3 scrapy shell h
  • C++入门基础04:代码实战经验分享(全局变量与局部变量重名、静态变量、数据类型选取、养成变量创建就初始化、少用多层指针)

    C 入门基础04 代码实战经验分享 全局变量与局部变量重名 静态变量 数据类型选取 养成变量创建就初始化 少用多层指针 1 全局变量与局部变量重名 include
  • $.ajax %5b%5d,%5Bobject%20Object%5D试图通过AJAX

    提交我想通过ajax传递变量到PHP脚本 将运行一个MySQL查询时 404未找到 但是 我不断收到错误404 Not Found with http myurl database 5Bobject 20Object 5D 5Bobject
  • 防火墙NAT配置实验

    目录 一 NAT的种类 分为基于源IP的转换 基于目的的IP转换 外部用户找内部服务器 二 实验拓扑 登陆防火墙 三 配置NAT 配置接口 实验一 配置no pat NAT 测试no pat 实验二 NAPT配置 NAPT测试 实验三 配置
  • web目录扫描工具dirscan

    成果 在扫描之前 我们首先要对url进行整理 因为我使用的是requests模块 所以我的url要用http 开头 所以我的判断代码是 if url startswith http url url elif url startswith h
  • 制作跟mnist一样格式的数据集(4)

    1将这篇文章https blog csdn net it job article details 80520975中自己制作的图片作为训练集 自己手写的 2将这篇文章https blog csdn net it job article de
  • ROS通信编程_服务编程_客户端编程

    系统环境 Ubuntu16 04 实现一个客户端 1 初始化ROS节点 2 创建一个Client实例 3 发布服务请求数据 4 等待Server处理之后的应答结果 在功能包 src下新建文件client cpp 输入以下内容并保存退出 例程
  • 用ScrollView解决Android屏幕显示不全的问题

    当控件比较多而在界面不能完全显示时 如下图所示 可以用ScrollView解决上述问题 使其可以通过垂直滚动将最下面的控件显示出来 ScrollView也是一个Layout布局 可以让它内部的数据显示不下的时候出现滚动条 但需要注意的是 S
  • json对象的使用依赖:

    1 jackso依赖
  • java mysql 自动重连_JDBC实现Mysql自动重连机制的方法详解

    前言 本文主要给大家介绍的是关于jdbc实现mysql自动重连机制的相关内容 分享出来供大家参考学习 下面来一起看看详细的介绍 日志 using the connector j connection property autoreconne
  • JAVA的内存回收机制(快速入门版)

    java内存回收机制 内存回收 是JVM中垃圾回收器提供的一种用于在空闲时间不定时回收无任何对象引用的对象占据的内存空间的一种机制 引用 java中什么是引用 Person xiaoi new Person new person 以pers
  • 什么是NoSQL数据库?它与传统数据库有什么异同以及NoSQL的三大基石和四大类型

    1 NoSQL数据库的特点 灵活的可拓展性 NoSQL数据库在设计之初就是为了满足 横向扩展 的需求 灵活的数据模型 NoSQL数据库采用键 值 列族等非关系模型 允许在一个数据元素里存储不同类型的数据 与云计算紧密融合 NoSQL数据库凭
  • Java中的同步与锁机制详解

    作为Java程序员 我们都知道在编写多线程程序时 需要确保线程之间的同步与互斥 本文将详细介绍Java中的同步与锁机制 1 为什么需要同步与锁 在多线程环境中 如果多个线程同时访问共享资源 可能会导致数据不一致或其他不可预料的结果 为了解决
  • PTA -1012 数字分类

    1012 数字分类 20 分 给定一系列正整数 请按要求对数字进行分类 并输出以下 5 个数字 A 1 能被 5 整除的数字中所有偶数的和 A 2 将被 5 除后余 1 的数字按给出顺序进行交错求和 即计算 n 1 n 2 n 3 n 4
  • zigzag走线原理及应用

    电路板上弯弯扭扭的走线有什么用 往期文章 一文读懂高速互联的阻抗及反射 上 一文读懂高速互联的阻抗及反射 中 前面几篇文章有部分读者反馈太深奥 不好懂 要求来一点轻松易懂的 这不 它来了 本期文章我们来分享近期工作中的一个小故事 一段奇怪的
  • 数据结构学习——循环链表的使用

    一 循环链表的介绍 循环链表是一种特殊类型的链表 其中链表中的最后一个节点指向链表中的第一个节点 形成循环的结构 与普通链表相比 循环链表可以在链表中的任何位置进行遍历 并且可以方便地实现循环操作 在循环链表中 每个节点通常包含一个数据元素