• 苦逼的双向循环链表


    以前不怎么写链表,更不怎么用C++写链表,导致这次写双向循环的时候直接萎了。

    其实思想很简单,就是细节比较多……

    别的不说了,直接上代码。(第一,这个不是我写的,第二,这个是C)

    typedef int elemtype;
    typedef struct lnode //定义结点类型
    {
    elemtype data;
    struct lnode *next;
    struct lnode *prior;
    }lnode,*linklist;

    int initlist(linklist &L) //初始化单链表
    {
    L=(linklist)malloc(sizeof(lnode)); //表头附加结点
    if(!L) exit(-2);
    L->next=L;
    L->prior=L;
    return 1;
    }//初始化了一个空表

    void createlist(linklist &L) //尾插法生成双向循环链表
    {
    int x;
    linklist q=L;
    printf("请输入要插入元素的值(输入0结束): ");
    scanf("%d",&x);
    while(x){
    linklist p=(linklist)malloc(sizeof(lnode));
    p->data=x;
    q->next=p;
    L->prior=p;
    p->prior=q;
    p->next=L;
    q=p;
    scanf("%d",&x);
    }
    }

    void shuchulist(linklist &L) //遍历有头结点的双向循环链表
    {
    linklist p=L->next;
    while(p->next!=L){
    printf("%4d",p->data);
    p=p->next;
    }
    printf("%4d",p->data);
    printf(" ");
    }
    int lengthlist(linklist L){//通过链表的遍历来统计长度
    linklist p=L->next;
    int count=0;
    while(p!=L){
    p=p->next;
    count++;
    }
    return count;
    }

    int listdelete_i(linklist &L,int i){//删除带头结点的双向循环链表中第i个元素
    linklist p=L;
    int j=0;
    if(i>lengthlist(L)){
    return 0;
    }
    while(j<i){//寻找第i个结点,并令p指向此结点
    p=p->next; ++j;
    }
    p->prior->next=p->next;//删除结点p
    free(p);//释放结点p
    return 1;
    }

    int listdelete_x(linklist &L,elemtype x){//删除值为x的元素
    linklist p=L->next,q;
    int i=0;
    while(p!=L){
    if(p->data==x){
    q=p->next;
    p->next->prior=p->prior;
    p->prior->next=p->next;
    free(p);
    p=q;
    ++i;
    }
    else
    p=p->next;
    }
    return i;
    }

    void paixu(linklist L){//将链表排成非递减链表
    int t;
    linklist p;
    for(int i=1;i<lengthlist(L);i++){
    p=L->next;
    for(int j=0;j<lengthlist(L)-i;j++){
    if(p->data>p->next->data){
    t=p->data;
    p->data=p->next->data;
    p->next->data=t;
    }
    p=p->next;
    }
    }
    }

    void linklistinsert(linklist &L,elemtype e){//在非递减有序双向循环链表中实现插入元素e仍有序
    linklist p=L->next;
    linklist q=(linklist)malloc(sizeof(lnode));
    q->data=e;
    if(L->prior->data<e){//把元素e 插到最后
    L->prior->next=q;
    q->prior=L->prior;
    q->next=L;
    L->prior=q;
    }else{
    while(p->data<e){//找到第一个大于或等于e的元素
    p=p->next;
    }
    //把e插到第一个大于或等于它的元素之前
    p->prior->next=q;
    q->prior=p->prior;
    q->next=p;
    p->prior=q;
    }
    }

    int panduan(linklist L){//判断双向循环链表中元素是否对称
    linklist p=L->next,q=L->prior;
    if(lengthlist(L)%2){
    while(p->data==q->data&&p!=q){
    p=p->next;q=q->prior;
    }
    if(q==p)
    return 1;
    else
    return 0;
    }else{
    while(p->data==q->data&&p->next!=q){
    p=p->next;q=q->prior;
    }
    if(p->data==q->data)
    return 1;
    else
    return 0;
    }
    }

    void jioushu(linklist L){//把链表中奇数放到偶数之前
    linklist p=L->next,q,s;
    s=L->prior;
    while(p!=s){
    if(p->data%2)
    p=p->next;
    else{
    q=p->next;
    p->prior->next=p->next; p->next ->prior=p->prior;//把p从链表中取出
    p->prior=L->prior;
    L->prior->next=p;
    p->next=L;
    L->prior=p;
    p=q;
    }
    }
    }

    void main()
    {
    linklist La;
    int menu,flag,i,x,c;
    do{
    printf("1.利用尾插法建立双向循环链表链表 ");
    printf("2.遍历双向循环链表 ");
    printf("3.双向循环链表中删除一个指定元素 ");
    printf("4.在非递减有序双向循环链表中实现插入元素e仍有序 ");
    printf("5.判断双向循环链表中元素是否对称若对称返回1否则返回0 ");
    printf("6.设元素为正整型,实现算法把所有奇数排列在偶数之前 ");
    printf("0.退出 ");
    printf(" 请输入所选菜单(0-6): ");
    scanf("%d",&menu);
    switch(menu){
    case 1: initlist(La);createlist(La);break;
    case 2: printf("链表中的元素为: ");shuchulist(La);break;
    case 3: printf("请选择删除方式:1 删除值为x的结点 2 删除第i个结点 ");
    scanf("%d",&c);
    if(c==1){
    printf("请输入要删除元素的值: ");
    scanf("%d",&x);
    flag=listdelete_x(La,x);
    if(flag){
    printf("删除成功! ");
    printf("删除后的链表为: ");
    shuchulist(La);
    }else
    printf("删除失败! ");
    }else if(c==2){
    printf("请输入要删除的位置: ");
    scanf("%d",&i);
    flag=listdelete_i(La,i);
    if(flag){
    printf("删除成功! ");
    printf("删除后的链表为: ");
    shuchulist(La);
    }else
    printf("删除失败! ");
    }
    break;
    case 4: printf("把原始链表初始化为非递减有序列表为: ");
    paixu(La);
    shuchulist(La);
    printf("请输入要插入的元素的值: ");
    scanf("%d",&x);
    linklistinsert(La,x);
    printf("插入后的链表为: ");
    shuchulist(La);
    break;
    case 5: flag=panduan(La);
    if(flag)
    printf("链表对称! ");
    else
    printf("链表不对称! ");
    break;
    case 6: printf("排列之前为: ");
    shuchulist(La);
    jioushu(La);
    printf("排列之后为: ");
    shuchulist(La); break;
    case 0: exit(0);
    }
    }while(menu);

    仅仅留个资料而已。

  • 相关阅读:
    生日蛋糕 (搜索)
    C语言中将二维数组作为函数参数来传递
    HDU 1052 Tian Ji -- The Horse Racing (贪心)(转载有修改)
    HDU 1789 Doing Homework again(排序,DP)
    10.6 ip:网络配置工具
    10.7 netstat:查看网络状态
    10.19 dig:域名查询工具
    10.21 nmap:网络探测工具和安全/端口扫描器
    10.20 host:域名查询工具
    LeetCode Add Two Numbers 两个数相加
  • 原文地址:https://www.cnblogs.com/SueMiller/p/3641477.html
Copyright © 2020-2023  润新知