线性表——双链表

双链表也是线性表的一种,它的全称是:线性双向链接表,它有以下特点:
在每个节点中除包含有数值域外,设置有两个指针域,分别用以指向其前驱节点和后继节点。
既可以依次向后访问每一个节点,也可以依次向前访问每一个节点。
这里写图片描述

dlinklist.h如下:

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


typedef int ElemType;
typedef struct Node{
    ElemType data;
    struct Node * prior;
    struct Node * next;
}DLinkList;

DLinkList.cpp如下:

#include "dlinklist.h"
#include <stddef.h>
void headInit(DLinkList * &dll,ElemType arr[], int n);
void printDoubleLinkList(DLinkList * dll);
void tailInit(DLinkList * &dll,ElemType arr[], int n);
bool insertElement(DLinkList *&dll, int pos, ElemType e);
bool deleteElement(DLinkList *&dll, int pos, ElemType &e);
int main() {
    DLinkList * dll;
    ElemType arr[] = {1,2,3,4,5};
    headInit(dll,arr,5);
    printf("头插法:\t");
    printDoubleLinkList(dll);

    tailInit(dll,arr,5);
    printf("尾插法:\t");
    printDoubleLinkList(dll);

    insertElement(dll,3,6);
    printf("在第3个位置上插入6之后:\t");
    printDoubleLinkList(dll);

    ElemType e;
    deleteElement(dll,3,e);
    printf("删除第3个元素之后:\t");
    printDoubleLinkList(dll);
}

//头插法
void headInit(DLinkList * &dll,ElemType arr[], int n){
    int i;
    dll = (DLinkList *) malloc(sizeof(DLinkList));
    //头节点两个指针为NULL
    dll->next = dll->prior = NULL;
    DLinkList * node;
    for(i = 0; i<n; i++){
        node = (DLinkList *) malloc(sizeof(DLinkList));
        node->data = arr[i];
        /*
         *插入,画图,依次赋值node->next,node->prior,dll->next(dll->prior永远为null)
         *可以发现除了第一次插入,以后插入的节点都要设置dll->next->prior = node
         */
        node->next = dll->next;
        if(dll->next != NULL){
            dll->next->prior = node;
        }
        node->prior = dll;
        dll->next = node;
    }
}

//尾插法
void tailInit(DLinkList * &dll,ElemType arr[], int n){
    int i;
    dll = (DLinkList *) malloc(sizeof(DLinkList));
    //头节点两个指针为NULL
    dll->next = dll->prior = NULL;
    DLinkList * node, *r;
    r = dll;
    for (i = 0; i < n; ++i) {
        node = (DLinkList *) malloc(sizeof(DLinkList));
        node->data = arr[i];
        //尾插,画图很简单
        node->prior = r;
        r->next = node;
        r=node;
    }
    r=NULL;
}

//插入节点,找出前一个节点
bool insertElement(DLinkList *&dll, int pos, ElemType e){
    int i = 0;
    DLinkList *p = dll, *node;
    while(i<pos-1 && p!=NULL){
        p = p->next;
        i++;
    }
    if(p==NULL){
        printf("插入的位置不合法");
        return false;
    }else{
        //分配节点
        node = (DLinkList *)malloc(sizeof(DLinkList));
        node->data = e;
        node->next = p->next;
        node->prior = p;
        if(p->next != NULL){
            p->next->prior = node;
        }
        p->next = node;
        return true;
    }
}

bool deleteElement(DLinkList *&dll, int pos, ElemType &e){
    int i = 0;
    DLinkList *p = dll, *node;
    while(i<pos-1 && p!=NULL){
        p = p->next;
        i++;
    }
    if(p==NULL){
        return false;
    }else{
        node = p->next;
        if(node == NULL){//如果p是尾节点,要删除的是尾节点的下一个节点,错误
            return false;
        }
        e = node->data;
        p->next = node->next;
        if(p->next != NULL){ //此时p->next已经改变,如果node->next为NULL.NULL不需要设置prior
            node->next->prior = p;
        }
        free(node);
        return true;
    }

}
void printDoubleLinkList(DLinkList * dll){
    //不需要输出头节点的data
    DLinkList *p = dll->next;
    while(p != NULL){
        printf("%d\t",p->data);
        p = p->next;
    }
    printf("\n");
}

输出结果为:

头插法:    5   4   3   2   1   
尾插法:    1   2   3   4   5   
在第3个位置上插入6之后:   1   2   6   3   4   5   
删除第3个元素之后:  1   2   3   4   5   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值