作业二 双向链表
首先我们来看双向链表的定义 :
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 插入2
void 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;
}其他的插入删除思路可以参考上面,剩下的比较简单就不说了

浙公网安备 33010602011771号