创建及初始化链表,以及打印链表,与单链表类似,采用尾插法实现。
链表自动初始化数据为L= 1 2 3 4;
要交换的结点的rear(下一个元素的地址)更改的方式与单链表方式方法一样,参考上一篇通过修改指针指向进行单链表的结点交换(C语言);
交换的结点的front的思路如下图:以交换1 4为例
每执行完一个操作后,链表对应颜色的连接会断开,方便查找,以防止代码出现:引发了未经处理的异常:读取访问权限冲突。 p 是 nullptr。此类错误。
最好通过一步一步调试去直观的看一下双链表在内存中的存储。用以加深理解。
代码实现如下:
struct node
{
int val;
struct node* front;
struct node* rear;
};
typedef struct node* Ptr;
Ptr CreateList()
{
Ptr h = (Ptr)malloc(sizeof(struct node));
h->front = NULL;
h->rear = NULL;
//创建一个辅助指针
Ptr p = h;
int val = 1;
while (val <= 4)
{
Ptr node = (Ptr)malloc(sizeof(struct node));
node->val = val;
node->front = p;
node->rear = NULL;
p->rear = node;
p = p->rear;
val++;
}
return h;
}
void Print_ByRear(Ptr L)
{
Ptr p = L->rear;
if (p == NULL)
return;
while (p)
{
printf("%d ", p->val);
p = p->rear;
}
return ;
}
void Swap(Ptr L,int a,int b)
{
Ptr p = L->rear, P1 = NULL, P2 = NULL,tmp1 = NULL,tmp2 = NULL;
if (p == NULL)
{
printf("空表\n");
return;
}
while (p != NULL)
{
if (p->val == a) P1 = p;
if (p->val == b) P2 = p;
if (P1&&P2)
break;
p = p->rear;
}
if (P1 == NULL || P2 == NULL)
{
printf("交换元素不存在于表中。\n");
return;
}
if (P1&&P2)
{
//先修改rear
P1->front->rear = P2;
P2->front->rear = P1;
tmp1 = P2->rear;
P2->rear = P1->rear;
P1->rear = tmp1;
//再修改front
tmp1 = P1->front;
P1->front = P2->front;
P2->front = tmp1;
P2->front->front = P1;
}
}
int main()
{
int a = 0, b = 0;
Ptr L = NULL;
L = CreateList();
printf("Before exchange:");
Print_ByRear(L);
printf("\n");
printf("please scanf two element for exchange:");
scanf("%d %d", &a, &b);
Swap(L, a, b);
printf("\n");
printf("After xchange:");
Print_ByRear(L);
return 0;
}