双向链表: 指向前驱 元素 指向后继
piror | element | next |
对称性:
d->next->piror=d->piror->next=d
#include<iostream>
#include<string>
#include<fstream>
#include<iomanip>
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status; //Status 是函数返回值类型,其值是函数结果状态代码。
typedef int ElemType; //ElemType 为可定义的数据类型,此设为int类型
struct Point {
int x;//x坐标
int y;//y坐标
};
typedef struct DuLNode {
Point data; //数据域
struct DuLNode *prior; //前驱指针
struct DuLNode *next; //后继指针
} DuLNode, *DuLinkList;
int length;
Status InitDuList_L(DuLinkList &L) {
//构造一个空的双向链表L
L = new DuLNode; //生成新结点作为头结点,用头指针L指向头结点
L->next = NULL; //头结点的指针域置空
L->prior = NULL;
return OK;
}
DuLNode *GetElemP_DuL(DuLinkList L, int i) {
//在带头结点的双向链表L中查找第i个元素,返回结点的地址
int j;
DuLinkList p;
p = L->next;
j = 1; //初始化,p指向第一个结点,j为计数器
while (j < i && p) { //顺链域向后扫描,直到p指向第i个元素或p为空
p = p->next;
++j;
}
if (!p || j > i)
return NULL; //第i个元素不存在
return p;
} //GetElemP_DuL
Status ListInsert_DuL(DuLinkList &L, int i, Point e) { //算法2.13 双向链表的插入
//在带头结点的双向链表L中第i个位置之前插入元素e,i的合法值为1<=i<=表长+1
DuLinkList s, p;
if (!(p = GetElemP_DuL(L, i))) //在L中确定第i个元素的位置指针p
return ERROR; //p为NULL时,第i个元素不存在
if (i == 1) {//在双向链表的第一个元素上插入
s = new DuLNode; //生成新结点s
s->data = e; //将结点s数据置为e
DuLinkList p = L->next;
L->next = s;
s->prior = L;
s->next = p;//将结点*s插入L中
p->prior = s;
++length;
} else if (i == length) {//在双向链表的最后一个元素上插入
s = new DuLNode; //生成新结点s
s->data = e; //将结点s数据置为e
DuLinkList p = L;
while (p->next)
p = p->next;//将LinkList p指向双向链表结尾
p->next = s;
s->prior = p;//将结点*s插入到p的后面,插入到L中
s->next = NULL;
++length;
} else {
s = new DuLNode; //生成新结点*s
s->data = e; //将结点*s数据域置为e
s->prior = p->prior; //将结点*s插入L中
p->prior->next = s;
s->next = p;
p->prior = s;
++length;
}
return OK;
} //ListInsert_DuL
Status ListDelete_DuL(DuLinkList &L, int i) { // 双向链表的删除
//删除带头结点的双向链表L中第i个位置之前插入元素e,i的合法值为1<=i<=表长
DuLinkList p;
if (!(p = GetElemP_DuL(L, i))) //在L中确定第i个元素的位置指针p
return ERROR; //p为NULL时,第i个元素不存在
if (i == 1)//删除双向链表的第一个元素
L = L->next;
else if (i == length) {//删除双向链表的最后一个元素
p->prior->next = NULL;
delete p;
--length;
return OK;
} else {
p->prior->next = p->next; //修改被删结点的前驱结点的后继指针
p->next->prior = p->prior; //修改被删结点的后继结点的前驱指针
delete p; //释放被删结点的空间
--length;
return OK;
}
}//ListDelete_DuL
void CreateDuList_L(DuLinkList &L, int m)
{
//正位序输入n个元素的值,建立带表头结点的双向链表L,同时建立前驱指针
DuLinkList r, p;
L = new DuLNode;
L->next = NULL; //先建立一个带头结点的空链表
r = L;//尾指针r指向头结点
length = 0;
while (m--)
{
p = new DuLNode;
cin >> p->data.x >> p->data.y; //输入元素值
p->next = NULL;
r->next = p;
r = p;
length++;
}
}
void Exchange(DuLinkList p)
{
DuLNode* temp1=p->prior,*temp2=p->next;
p->prior = temp1->prior;
temp2->prior = temp1;
p->next = temp1;
temp1->prior->next = p;
temp1->prior = p;
temp1->next = temp2;
}
void output(DuLinkList L)
{
//双向链表的输出
DuLinkList p = L->next;
while (p)
{
cout << p->data.x << " " << p->data.y << endl;
p = p->next;
}
}
int main()
{
int a;
DuLinkList L, p;
InitDuList_L(L);
int n;
cin >> n;
CreateDuList_L(L, n);
scanf("%d", &a);
p = GetElemP_DuL(L, a);
Exchange(p);
output(L);
return 0;
}
插入:
删除:
头指针:指向链表第一个结点的指针
头结点:在首元结点值之前设的一个节点,指针域指向首元结点,没有直接前驱
表头结点:也称首元结点,是链表中存储的第一个数据元素的结点。