您的位置:首页 > 理论基础 > 数据结构算法

作业二 双向链表

2017-10-21 14:22 148 查看
   首先我们来看双向链表的定义  :

typedef  int ElemType;
typedef struct Node * PtrToNode;
typedef PtrToNode Position;
struct DListNode;
typedef DListNode * DList;

typedef struct Node
{
ElemType data; /*数据域*/
PtrToNode previous; /*指向前驱*/
PtrToNode next;		/*指向后继*/
}Node;

struct DListNode
{
PtrToNode head;		/*指向头节点*/
PtrToNode tail;		/*指向尾节点*/
int size;  //链表中数据项数
}

   示意图大概是这样的



DListNode是什么呢?相当于一个指路牌,让你可以直接走向头结点或尾节点。

        双向链表要注意的是,如果只有一个节点 A,那么A既是头结点,也是尾节点。

        所以我们在写插入删除操作的时候要进行分类讨论。

2264,插入 I

void InsertAtHead(DList L, ElemType x)
{
Position p = (PtrToNode)malloc(sizeof(Node));
p->data = x;
if (L->head == NULL)
{
L->head = p;
L->tail = p;
p->next = NULL;
p->previous = NULL;
}
else {
p->next = L->head;
L->head->previous = p;
L->head = p;
p->previous = NULL;
}
L->size++;
}

//链表链接的时候基本准则都是  先连接再断开 ,虽然两个指针操作有点麻烦,但是还是比较好理解的

2265  插入2void InsertAtTail(DList L, ElemType x)
{
Position p = (PtrToNode)malloc(sizeof(Node));
p->data = x;
if (L->tail == NULL)
{
L->head = p;
L->tail = p;
p->next = NULL;
p->previous = NULL;
}
else
{
p->previous = L->tail;
L->tail->next = p;
L->tail = p;
p->next = NULL;
}
L->size++;
}

2271,删除 I

void DelFirst(DList L, ElemType *e)
{
Position p = L->head;
if (L->size == 0) return;
if (L->tail == p)
{
L->head = NULL;
L->tail = NULL;
}
else {
L->head = p->next;
p->next->previous = NULL;
p->next = NULL;
}
*e = p->data;
free(p);
L->size--;
}

2272 删除 II

void DelLast(DList L, ElemType *e)
{
Position p = L->tail;
if (L->size == 0) return;
if (L->head == p)
{
L->head = NULL;
L->tail = NULL;
}
else {
L->tail = p->previous;
p->previous->next = NULL;
p->previous = NULL;
}
*e = p->data;
free(p);
L->size--;
}

链表清空(非销毁的时候)要把每项数字清零,并改正size的值(head、tail指向空别忘了)

2275 双向链表的清空

void ClearList(DList L)
{
Position p = L->head;
while (p != L->tail)
{
p->data = 0;
p = p->next;
}
L->size = 0;
L->head = NULL;
L->tail = NULL;
}

其他的插入删除思路可以参考上面,剩下的比较简单就不说了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息