zoukankan      html  css  js  c++  java
  • 双向循环链表

    #include<stdio.h>
    #include<stdlib.h>
    #include<malloc.h>
    #include<assert.h>
    
    //双向循环链表的结构体定义
    typedef struct node
    {
        int data;
        struct node *prior;
        struct node *next;
    }NODE,*PNODE,*LINKLIST;
    
    //初始化
    void init(LINKLIST *list)
    {
        *list = (PNODE)malloc(sizeof(NODE));
        (*list)->next = *list;
        (*list)->prior = *list;
    }
    
    //添加
    void add(LINKLIST list,int data)
    {
        PNODE p=list,q;
        q=(PNODE)malloc(sizeof(NODE));//q为要插入的节点
        q->data =data;
        q->next = p;
        q->prior = p->prior;
        if(p->prior)
            p->prior->next = q;
        p->prior = q;
    }
    
    //插入 i>=1
    void insert(LINKLIST list,int i,int data)
    {
        PNODE p=list,q;
        //将p移动到i-1个位置
        while(--i && p->next!=list)
        {
            p=p->next;
        }
        assert(i==0);
        q = (PNODE)malloc(sizeof(NODE));//q为需要插入的节点
        q->data =data;
        q->next = p->next;
        q->prior = p;
        if(p->next)
            p->next->prior = q;
        p->next = q;
    }
    
    //删除
    void del(LINKLIST list,int i,int *data)
    {
        PNODE p=list,q;
        //将p移动到第i-1个位置
        while(--i && p->next!=list)
        {
            p=p->next;
        }
        assert(i==0 && p->next!=list);
        q = p->next;//q为要删除的节点
        *data = q->data;//将删除的节点的数据域返回
        p->next = q->next;//p断开与q连接,和q的后继相连
        if(q->next)
            q->next->prior = p;//如果删除节点存在后继,那么将这个的prior的指向p
    }//end del
    
    //获取双向循环链表的长度
    int getLen(LINKLIST list)
    {
        PNODE p=list;
        int i=0;
        while((p=p->next)!=list)
        {
            i++;
        }
        return i;
    }
    
    //获取第i个位置的数据
    int getData(LINKLIST list,int i)
    {
        PNODE p=list;
        //将p移动到第i个位置
        while(i--)
        {
            p=p->next;
            assert(p!=list);
        }
        return p->data;
    }
    //正转一圈输出
    void display1(LINKLIST list)
    {
        PNODE p=list;
        while((p=p->next)!=list)
        {
            printf("%d ",p->data);
        }//end while
        printf("
    ");
    }
    
    //正转两圈输出
    void display2(LINKLIST list)
    {
        int count=0;//统计p转到list个数
        PNODE p=list;
        while(count<2)
        {
            p=p->next;
            if(p==list)
            {
                count++;
                continue;
            }else
            {
                printf("%d ",p->data);
            }
        }
        printf("
    ");
    }
    
    //反转一圈输出
    void display_1(LINKLIST list)
    {
        PNODE p=list;
        while((p=p->prior)!=list)
        {
            printf("%d ",p->data);
        }
        printf("
    ");
    }
    
    //反转两圈输出
    void display_2(LINKLIST list)
    {
        int count=0;//统计p转到list个数
        PNODE p=list;
        while(count<2)
        {
            p=p->prior;
            if(p==list)
            {
                count++;
                continue;
            }else
            {
                printf("%d ",p->data);
            }
        }
        printf("
    ");
    }
    
    //销毁
    void destroy(LINKLIST *list)
    {
        PNODE p = *list,q;
        while(p->next != *list)
        {
            q=p->next;
            free(p);
            p = q;
        }
        *list = NULL;
    }
    
    //显示菜单
    void displaymenu()
    {
        printf("**********这是一个双向循环链表的基本操作程序**********
    ");
        printf("			1,添加
    ");
        printf("			2,插入
    ");
        printf("			3,删除
    ");
        printf("			4,获取长度
    ");
        printf("			5,获取数据
    ");
        printf("			6,正转输出一圈
    ");
        printf("			7,正转输出两圈
    ");
        printf("			8,反转输出一圈
    ");
        printf("			9,反转输出两圈
    ");
        printf("			0,销毁退出
    ");
    }//end displaymenu
    
    int main()
    {
        int i,j,choice,flag=1;
        LINKLIST list=NULL;
        init(&list);//初始化链表
        displaymenu();//显示菜单
        while(flag)
        {
            printf("请选择你要的操作:");
            scanf("%d",&choice);//输入
            switch (choice)
            {
            case 1:
                printf("--你当前选择了添加操作-- (说明:按组合键ctrl+Z并回车可结束添加操作)
    ");
                while(scanf("%d",&i)!=EOF)
                {
                    add(list,i);
                }//end while
                printf("--添加操作结束--
    
    ");
                break;
            case 2:
                printf("--你当前选择了插入操作--
    ");
                printf("--请输入插入元素的数据:");
                scanf("%d",&j);
                printf("--请输入插入位置:");
                scanf("%d",&i);
                insert(list,i,j);
                printf("--插入结束--
    
    ");
                break;
            case 3:
                printf("--你当前选择了删除操作--
    ");
                printf("--请输入删除位置:");
                scanf("%d",&i);
                del(list,i,&j);
                printf("--你删除的元素的数据:%d 
    ",j);
                printf("--删除结束--
    
    ");
                break;
            case 4:
                printf("--你当前选择了获取长度操作--
    ");
                printf("双向循环链表的长度:%d
    ",getLen(list));
                printf("--获取表长结束--
    
    ");
                break;
            case 5:
                printf("--你当前选择了获取数据操作--
    ");
                printf("--请输入你要获取元素的位置:");
                scanf("%d",&i);
                printf("第%d个位置的数据为:%d
    ",i,getData(list,i));
                printf("--获取数据结束--
    ");
                break;
            case 6:
                printf("--你当前选择了正转输出一圈操作--
    ");
                display1(list);
                printf("--正转输出一圈操作结束--
    
    ");
                break;
            case 7:
                printf("--你当前选择了正转输出两圈操作--
    ");
                display2(list);
                printf("--正转输出两圈操作结束--
    
    ");
                break;
            case 8:
                printf("--你当前选择了反转输出一圈操作--
    ");
                display_1(list);
                printf("--反转输出一圈操作结束--
    
    ");
                break;
            case 9:
                printf("--你当前选择了反转输出两圈操作--
    ");
                display_2(list);
                printf("--反转输出两圈操作结束--
    
    ");
                break;
            case 0:
                printf("--你当前选择了销毁并退出操作--
    ");
                destroy(&list);//销毁链表
                flag=0;//退出循环
                printf("--退出操作结束--
    
    ");
                break;
            default:
                printf("--你选择错误!
    
    ");
                break;
            }//end switch
        }//end while(flag)
    
        
        system("pause");
        return 0;
    }
  • 相关阅读:
    HTTP 协议中的并发限制及队首阻塞问题
    聊聊JMM
    聊聊CacheLine
    git解决本地建立git仓库 连接远程git仓库出现拒绝合并问题
    django 本地项目部署uwsgi 以及云服务器部署 uwsgi+Nginx+Docker+MySQL主从
    我的第一篇播客
    大爷的超市管理系统——冲刺第一天
    能混绝不C——凡事预则立
    2020软件工程团队作业——05
    2020软件工程作业——04
  • 原文地址:https://www.cnblogs.com/dzqdzq/p/3404212.html
Copyright © 2011-2022 走看看