双向链表

解释,我们在单链表中,有了next指针,查找下一元素为O(1),而查找上一节点的话,则是O(n)。
所以为了克服单向性这一缺点,我们在单链表的每个节点中,在设置一个指向其前区节点的指针域。

#include "string.h"
#include "ctype.h"

#include "stdio.h"
#include "stdlib.h"
#include "io.h"
#include "math.h"
#include "time.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 1000 /* 存储空间初始分配量 */
typedef int ElemType ;
typedef int status  ;

typedef struct DulNode{
    ElemType data;
    struct DulNode * next;
    struct DulNode * prior;
}DulNode,*DuLinkList;

//typedef struct DulNode* DuLinkList; 和上述表示方法一样
status InitList(DuLinkList * L){
 (*L) =(DuLinkList) malloc(sizeof(DulNode));
    if(*L == NULL){
        return ERROR;
    }else{
        (*L)->next = NULL;
        (*L)->prior = NULL;
        return OK;
    }
}

status EemptyList(DuLinkList L){
    if(L->next == NULL){
        return ERROR;
    }else{
        return OK;
    }

}

status Inserthead(DuLinkList **L,ElemType e){
    DuLinkList first;
    first = (DuLinkList)malloc(sizeof(DulNode));
    first->data = e;
    //printf("%p\n",(*(*L)));

    (*(*L))->next = first;
    first->prior = (*(*L));
    first->next = NULL;
    return -1;
}

status InsertTail(DuLinkList *L,ElemType e){//从表尾插 //
    DuLinkList rear;
    rear = (DuLinkList)malloc(sizeof(DulNode));
    rear->data = e;
    (*L)->next = rear;
    rear->prior = (*L);
    rear->next = NULL;

return 1;
}

status ListInsert(DuLinkList *L , int i, ElemType e){//考虑没有节点和插入到第一个位置
    if(!EemptyList(*L))
       return Inserthead(&L,e);
    DuLinkList p = (*L);
    int j=1;
    while(p && j<i ){
        p = p->next;
        j++;
    }
    if(!p||j>i){//用于判断i大于公共的节点数越界的情况和i=0的情况
        return ERROR;
    }

    if(p->next == NULL){//最后一个位置的后一个位置
       InsertTail(&p,e); //传p不用重新遍历
       return -1;
    }

    DuLinkList q = (DuLinkList)malloc(sizeof(DulNode));
    q->data = e;
    q->next = p->next;
    q->prior=p;
    p->next->prior = q;
    p->next = q;

}

status GetElem(DuLinkList L ,int i , ElemType *e){  //L指向头结点 L叫头指针

    int j=1;
    DuLinkList p = L->next;//指向第一个节点
    while(p&&j<i){
      j++;
      p = p->next;
    }
    if(!p||j>i){
      return ERROR;
    }

    *e = p->data;
    return OK;

}

status DeleteList(DuLinkList * L , int i ,ElemType *e){//由于是双向链表没有必要再去找到i-1个位置
    if(!EemptyList(*L))
    return ERROR;
    int j=1;
    DuLinkList p = (*L)->next; //从第一个位置开始
    while(p&&j<i){
        j++;
        p=p->next;
    }
    if(!p||j<i){
        printf("dasdasd\n");
        return ERROR;
    }

    *e = p->data;
    if(p->next==NULL){ //删除最后一个元素
        p->prior->next = NULL;
        free(p);
        return OK;
    }


    p->prior->next = p->next;
    p->next->prior = p->prior;
    free(p);
    return OK;

}

int ListLength(DuLinkList L){
    if(!EemptyList(L))
    return 0;

    int j=0;
    DuLinkList p = L->next;
    while(p){
        j++;
        p = p->next;
    }

return j;
}

status FromHeadInsert(DuLinkList *L ,int n){

    (*L) =(DuLinkList) malloc(sizeof(DulNode));
    (*L)->next  = NULL;
    (*L)->prior = NULL;
    int i;
    srand(time(0));
    DuLinkList q=NULL;//用于记录原第一个节点的位置
    for(i=0;i<n;i++){
        DuLinkList s;
        s = (DuLinkList) malloc(sizeof(DulNode));
        s->data = rand()%100+1;
        s->prior = (*L);
        s->next = q;
        if(i!=0)
        (*L)->next->prior = s;//除了第一次插入的节点外,以后每次插
                             //入都需要设置原来的节点的前一个指向新的节点
        //q->prior = s 也可以

        (*L)->next = s;
        q=s;
    }


return OK;
}

status FromTailInsert(DuLinkList *L ,int n){
    (*L) =(DuLinkList) malloc(sizeof(DulNode));
    (*L)->next  = NULL;
    (*L)->prior = NULL;
    int i;
    srand(time(0));
    DuLinkList q=(*L);//用于记录原节点的位置
     for(i=0;i<n;i++){
        DuLinkList s;
        s = (DuLinkList) malloc(sizeof(DulNode));
        s->data = rand()%100+1;
        s->prior = q;
        s->next = NULL;
        q->next = s;
        q=s;
    }
}

status ClearList(DuLinkList *L){
    if(!EemptyList(*L))
    return ERROR;
    DuLinkList p=(*L)->next,q;
    while(p){
      q=p->next;
      free(p);
      p=q;
    }
    (*L)->next  = NULL;
    (*L)->prior = NULL;
    return OK;
}

int LocateElem(DuLinkList L,ElemType e){
    if(!EemptyList(L))
    return ERROR;
    DuLinkList p=L->next;
    int i=1;
    while(p){
        if(p->data == e)
        {
          return i;
        }
        p=p->next;
        i++;

    }
    return ERROR;
}
int main(){
    DuLinkList node;
    InitList(&node);
    //判读是否为空
    printf("%d\n",EemptyList(node));
    ListInsert(&node,1,2);//从头插
    printf("%p\n",node);
   // printf("%d\n",node->next->data);
    ListInsert(&node,1,5);
    ListInsert(&node,2,7);
    ListInsert(&node,2,9);
    ListInsert(&node,5,19);//插入到最后一个位置的下一个
    DuLinkList first,first1;
    first = node->next;
     while(first){
        printf("%d\n",first->data);
        first1 = first;
        first= first->next;
    }
     printf("\n");
     while(first1!=node){
        printf("%d\n",first1->data);
        first1= first1->prior;
    }
    printf("\n");
//得到元素
int value;
GetElem(node,5,&value);
printf("%d\n",value);

//删除元素
printf("\n");
printf("%d\n",DeleteList(&node,1,&value));
//printf("%d\n",value);
first = node->next;
     while(first){
        printf("%d\n",first->data);
        first1 = first;
        first= first->next;
    }
    printf("\n");
     while(first1!=node){
        printf("%d\n",first1->data);
        first1= first1->prior;
    }
printf("\n");
//计算长度
int chang = ListLength(node);
printf("%d\n",chang);
//头插法
printf("\n");
DuLinkList HeadInsert,test,test1;
FromHeadInsert(&HeadInsert,10);
test = HeadInsert->next;
     while(test){
        printf("%d\n",test->data);
        test1 = test;
        test= test->next;
    }
   printf("\n");
    while(test1!=HeadInsert){
        printf("%d\n",test1->data);
        test1= test1->prior;
    }
printf("\n");
//尾插法
DuLinkList TailInsert;
FromTailInsert(&TailInsert,3);
test = TailInsert->next;
     while(test){
        printf("%d\n",test->data);
        test1 = test;
        test= test->next;
    }
   printf("\n");
    while(test1!=TailInsert){
        printf("%d\n",test1->data);
        test1= test1->prior;
    }
      printf("\n");
//清空链表
printf("%p\n",TailInsert);
ClearList(&TailInsert);
printf("%p\n",TailInsert);

//查找相等元素的位置

int result = LocateElem(node,19);
printf("%d\n",result);
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值