双链表

双链表:

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。

双链表的一些基本操作函数的声明:

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

typedef struct Node {
    int data;
    struct Node * next;
    struct Node * prior;
}Node, *Pnode;
Pnode create_list(void);    //创建节点
void traverse_list(Pnode pHead);    //遍历链表打印 
void fantraverse_list(Pnode pHead);
int ListLength(Pnode pHead);
Pnode ListInsert(Pnode pHead); 
Pnode ListDelete(Pnode pHead, int x);
Pnode ListSort(Pnode pHead); 
void ListClear(Pnode pHead);

创建双链表的历程:

Pnode create_list(void)
{
    int i, len;
    Pnode pHead, pTemp;
    pHead = (Pnode)malloc(sizeof(Node));
    Pnode pNew;
    if(NULL == pHead){
        printf("内存分配出错!\n");
        exit(1);
    } 
    pHead = pTemp;
    pTemp->next = NULL;
    printf("请输入你想要的链表的长度:");
    scanf("%d", &len);
    for(i = 0; i < len; i++){
        pNew = (Pnode)malloc(sizeof(Node));
        if(NULL == pNew){
            printf("新节点内存分配出错。\n");
            exit(1);
        }
        printf("请输入新节点的值:");
        scanf("%d", &pNew->data);
        pTemp->next = pNew;
        pNew->prior = pTemp;
        pNew->next = NULL;
        pTemp = pNew;
    }
    (pHead->next)->prior = NULL;
    return pHead;
}

由前向后遍历:

void traverse_list(Pnode pHead){
    Pnode pTemp = pHead->next; 
    if(pTemp == NULL){
        printf("链表为空。\n");
    }
    else{
        printf("由前到后链表的值分别是:");
        while(pTemp){
            printf("%d ", pTemp->data);
            pTemp = pTemp->next;
        }
    }
    printf("\n"); 
}

由后向前遍历:

void fantraverse_list(Pnode pHead){
    Pnode pTemp = pHead->next;
    if(pTemp == NULL){
        printf("链表为空。\n");
        exit(1);
    }
    while(pTemp->next != NULL){
        pTemp = pTemp->next;
    }
    printf("由后到前链表的值分别是:");
    while(pTemp){
        printf("%d ", pTemp->data);
        pTemp = pTemp->prior;
    }
    printf("\n");
}

插入历程:

Pnode ListInsert(Pnode pHead){
    int x;
    printf("请输入你想在那个值得前面或后面插:");
    scanf("%d", &x);
    Pnode pTemp = pHead->next;
    Pnode pInsert, pTemp2;
    while(pTemp && pTemp->data != x){
        pTemp = pTemp->next; 
    }
    if(pTemp == NULL){
        printf("在链表中没有找到%d的值。\n", x);
        return pHead;
    }
    else{
        pInsert = (Pnode)malloc(sizeof(Node));
        int s;
        printf("请输入要插入元素的值:");
        scanf("%d", &pInsert->data);
        printf("请选择插在%d之前还是之后。(“0”前“1”后)", x);
        do{ 
            scanf("%d", &s);
            if(s == 0){
                if(pTemp->prior == NULL){
                    pHead->next = pInsert;
                    pTemp->prior = pInsert;
                    pInsert->next = pTemp;
                    pInsert->prior = NULL;
                    break;
                }
                pTemp2 = pTemp->prior;
                pInsert->next = pTemp;
                pInsert->prior = pTemp2;
                pTemp2->next = pInsert;
                pTemp->prior = pInsert;
            }
            if(s == 1){
                if(pTemp->next == NULL){
                    pTemp->next = pInsert;
                    pInsert->prior = pTemp;
                    pInsert->next = NULL;
                    break;
                }
                pTemp2 = pTemp->next;
                pInsert->next = pTemp2;
                pInsert->prior = pTemp;
                pTemp->next = pInsert;
                pTemp2->prior = pInsert; 
            }
        }while(!(s == 0 || s == 1));
    }

    return pHead;
}

删除历程:

Pnode ListDelete(Pnode pHead, int x){
    Pnode pTemp = pHead;
    while(pTemp->next && pTemp->next->data != x){
        pTemp = pTemp->next;
    }
    if(pTemp->next == NULL){
        printf("链表中没找到%d。\n", x);
        return pHead;
    }
    Pnode pTemp2 = pTemp->next;
    if(pTemp2 == pHead->next){
        pHead->next = pTemp2->next;
        (pTemp2->next)->prior = NULL;
    }
    else if(pTemp2->next == NULL){
        pTemp->next = NULL;
    }
    else{
        Pnode pTemp2 = pTemp->next;
        pTemp->next = pTemp2->next;
        (pTemp2->next)->prior = pTemp;
    }
    free(pTemp2);
    return pHead;
}

链表排序:

Pnode ListSort(Pnode pHead){
    Pnode pFirst;
    Pnode pMin;
    Pnode pFmin;
    Pnode pTail;
    Pnode pTemp;
    Pnode pTemp2;
    if(pHead->next == NULL){ 
        printf("链表为空!\n");
        return pHead;
    }
    if(pHead->next->next == NULL){
        printf("只有一组数据无需排序");
    }
    pFirst = NULL; 
    while(pHead->next != NULL){
        for(pTemp = pHead, pMin = pHead->next; pTemp->next != NULL; pTemp = pTemp->next){
            if(pMin->data > pTemp->next->data){
                pFmin = pTemp;
                pMin = pTemp->next;
            }
        }
        if(pFirst == NULL){
            pFirst = pMin;
            pFirst->prior = NULL;
            pTail = pMin;
        }
        else{
            pTail->next = pMin;
            pMin->prior = pTail;
            pTail = pMin;
        }
        if(pHead->next == pMin)
            pHead->next = pMin->next;
        else
            pFmin->next = pMin->next;
    }
    pTail->next  = NULL;
    pHead->next = pFirst;

    return pHead;
}

销毁链表

void ListClear(Pnode Phead){
    Pnode pTemp = Phead;
    Pnode pTemp2;
    while(pTemp != NULL){
        pTemp2 = pTemp->next;
        free(pTemp);
        pTemp = pTemp2;
    }
}

一个测试 函数:

int main(void)
{
    Pnode head = create_list();
    traverse_list(head);
    fantraverse_list(head);
    printf("链表的长度是:%d\n", ListLength(head)); 
    head = ListInsert(head);
    traverse_list(head);
    fantraverse_list(head);
    int x;
    printf("请输入你想删除的值:");
    scanf("%d", &x);
    head = ListDelete(head, x);
    traverse_list(head);
    fantraverse_list(head); 
    printf("排序后的链表:");
    head = ListSort(head);
    traverse_list(head);
    fantraverse_list(head);
    ListClear(head);
    return 0;
}

有几个函数没写^.^

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值