表-双链表(list/doubly-linked-list)

双链表

链表是表ADT的一种链式映像。双链表是链表的一种,即每个结点有两个指针域,一个指向前驱,一个指向后继。
(这里的链表是带有头结点的链表,头结点前驱指向最后一个结点,或无前驱)

双链表

双链表的结点的声明与定义如下:

//clare node
struct Node;
typedef struct Node *PtrToNode;
typedef struct PtrToNode Position;          //指向链表的结点的指针
typedef struct PtrToNode List;              //指向链表头的指针(分开来以示区分)

//define node
struct Node{
  Elementtype Element;
  Position Next;
  Position Prev;
};

双链表上的一些操作:

(其它可自定义)

  • int IsEmpty(List L);
  • int IsLast(List L, Position P);
  • Position Find(Elementtype x, List L); //找到x第一次出现的位置
  • void Delete(Elementtype x, List L); //删除第一次出现的x
  • void Insert(List L, Position P, Elementtype x); //在P之前插入一个结点,值为x
  • void DeleteList(List L);

双链表上对这些操作的定义:

双链表的例程的实现与单链表的实现相仿,仅有以下的一点差别:

  • 在插入的例程中,不用再去专门地写函数去查找前驱,因此实现起来更加地简单了。
  • 删除的例程中,删除结点的代码与单链表的有所差异。
//functions
int IsEmpty(List L) {
  return L->Next == NULL;
}
int IsLast(List L, Position P) {
  return P->Next == NULL;
}

Position Find(Elementtype x, List L) {    //找到x第一次出现的位置
  Position p;
  P = L->Next;

  while (P && P->Element != x)
    P = P->Next;

  return P;
}

void Delete(Elementtype x, List L) {     //删除第一次出现的x
  Position P = L->Next;

  while (P && P->Element != x) {
    P = P->Next;
  }
  if (P != NULL) {                      //当链表中存在x的时候
    P->Next->Prev = P->Prev;
    P->Prev->Next = P->Next;
    free(P);
  }
  return;
}

void Insert(List L, Position P, Elementtype x) { //在P之前插入一个结点,值为x
  //首先要确保P不是头结点
  if (P == L) {
    exit(1);
    return;
  }

  Position Q;
  Q = (Position)malloc(sizeof(Node));
  if(!Q){
    exit(1);
    return;
  }

  //insert
  Q->Prev = P->Prev;
  Q->Next = P;
  P->Prev->Next = Q;
  P->Prev = Q;

  return;
}

void DeleteList(List L) {
  Position P = L;
  while (P) {
    Position Q = P;
    P = P->Next;
    free(Q);
  }
}

至此双链表实现完毕

posted @ 2018-01-29 23:01  waterlemon  阅读(337)  评论(0编辑  收藏  举报