双链表基本操作的实现

#include
typedef int ElemType;

typedef struct DNode{
    ElemType data;
    struct DNode *prior,*next;
}DNode, *DLinkList;


//初始化链表,尾插法创建一个双链表
void CreatList(DLinkList *L){
    int x;
    (*L) = (DLinkList)malloc(sizeof(DNode));
    DNode *s,*p=*L;
    scanf("%d",&x);
    while(x!=999){
        s=(DNode *)malloc(sizeof(DNode));
        s->data = x;
        p->next = s;
        s->prior = p;
        p = s;
        scanf("%d",&x);
    }
    p->next = NULL;
}

//按序号查找结点值
int GetElem(DLinkList L,int i){
    int j = 1;
    DNode *p=L->next;
    if(i < 1)
    {
        printf("序号出错。");
    }
    while(p&&jnext;
        j++;
    }
    printf("序号%d的值为:%d",i,p->data);
}

//按值查找结点
int LocateElem(DLinkList L,ElemType e){
    int i = 1;
    DNode *p=L->next;
    if(p == NULL)
        printf("无此值。");
    while(p!=NULL&&p->data!=e){
        p = p->next;
        i++;
    }
    printf("值为%d的序号为:%d",e,i);
}

//指定位置插入元素
int ListInsert(DLinkList L,int i,ElemType e){
    i--;
    int j = 1;
    DNode *p = L->next;
    if(!p || i<1)
    {
        printf("序号出错。");
    }
    while(p&&jnext;
        j++;
    }
    DNode *s = (DLinkList)malloc(sizeof(DNode));
    s->data = e;
    s->next = p->next;
    p->next->prior = s;
    s->prior = p;
    p->next = s;
    return;
}

//指定位置删除元素
int ListDelete(DLinkList L,int i){
    i--;
    int j = 1;
    DNode *p=L->next;
    if(i < 1 || !p->next)
    {
        printf("序号出错。");
    }
    while(p&&jnext;
        j++;
    }
    DNode *q = p->next;
    p->next = q->next;
    q->next->prior = p;
    free(q);
    return 1;
}

//链表打印
int PrintList(DLinkList L){
    DLinkList p = NULL;
    p = L->next;
    int i = 0;
    while(p)
    {
        printf("%4d",p->data);
        p = p->next;
        i++;
    }
    if(i == 0)
    {
        printf("链表为空。");
    }
    return 1;
}

//删除链表
int clearList(DLinkList L){
    DNode *p = L->next;
    while(p)
    {
        DNode *q = p->next;
        free(p);
        p = q;
    }
    L->next = NULL;
    return 1;
}

int main(){
    int i,e;
    DLinkList list;
    printf("请输入建立的链表元素(输入999终止): \n");
    CreatList(&list);
    PrintList(list);
    printf("\n请输入要查询的序号:");
    scanf("%d",&i);
    GetElem(list,i);
    printf("\n请输入要查询的元素值:");
    scanf("%d",&e);
    LocateElem(list,e);
    printf("\n请输入需要插入元素的位置及元素值:");
    scanf("%d %d",&i,&e);
    ListInsert(list,i,e);
    PrintList(list);
    printf("\n请输入需要删除元素的位置:");
    scanf("%d",&i);
    ListDelete(list,i);
    PrintList(list);
    clearList(list);
    return 0;
}

1.双链表的引入:

 单链表的节点中只有一个指向其后继的指针,这使得单链表只能从头结点依次顺序的向后遍历。若要访问某个结点的

前驱结点(插入、删除操作时),只能从头开始遍历,访问后继结点的时间复杂度为O(1),访问前驱结点的时间复杂度

为O(n)。

为克服单链表以上缺点,引入双链表,双链表指针域中有两个指针prior和next,分别为其前驱结点和后继结点。

2.双链表的主要操作:

 双链表仅仅是在单链表的结点增加了一个指向前驱的prior指针,因此,在双链表中执行按序查找和按值查找的操作和单链表

的操作相同;但在插入和删除操作的实现上,需要对prior指针做出修改。

插入操作:

s->next = p->next;
p->next->prior = s;
s->prior = p;
p->next = s;
 删除操作:

p->next = q->next;
q->next->prior = p;
free(q);




你可能感兴趣的:(数据结构)