单链表,中只有一个指向其后继的指针,要访问某个节点兄弟,就只能从头开始遍历,访问后面时间复杂度O(1),访问前驱时间复杂度O(N);
为了向别人展示自己更快,某位聪明人发明了双链表.
双链表定义如下:
typedef struct DNode{
ElemType data;
struct DNode *prior;
struct DNode *next;
}DNode,*DLinkList;
现在可是有两个指针哦,一个前驱,一个后继,链路从单向变成双向了.
查找什么的与单链表基本没啥不同,但是删除,插入什么的会搞坏链表的东西肯定是要不同的,毕竟要保证链表不断.
看操作:
1.双链表的插入操作
首先看插入位置是否合法,然后找到要查的节点位置的前驱,这个和单链表是一样的.
假设前驱是p,插入s;
代码如下:
s->next=p->next,
p->next->prior=s;
p->next=s
s->prior=p;
思考如果在p节点之前插入s节点
代码:
p->prior->next=s;
s->prior=p->prior;
s->next=p;
p->prior=s;
2.双链表的删除操作
删除双链表中节点*p的后继节点*q,其指针的变化过程
删除过程很简单;
看代码:
p->next=q->next;
q->next->prior=p;
free(q);
思考:
如果删除的是节点*p的前驱节点*q;
操作代码:
思考题我也给代码就是玩.
q->prior->next=p;
p->prior=q->prior;
free(q);
双链表在学过单链表的基础上是不是很简单.
给你们看看我做的一道题:
将数组A[m+n]中的全部元素(a1,a2,....am,b1,b2,......bn),原地逆置位(b1,b2....bn,a1,a2,....am)
操作步骤:分段逆置就完事了'
先整体逆置为(bn,bn-1,.....b1,am,am-1,....a1)
在对(bn,bn-1,..b1)逆置为(b1,b2,.....bn)
在对(an,an-1,....a1)逆置为(a1,a2,.....am)
这不就搞定了.
看我输出代码:
//先写逆置函数
void Reverse(int A[],int left,int right,int arraysize)
{
if(left>=right||right>=arraysize)
{
return false;
}
int mid=(left+right)/2;
for(int i=0;i<=mid;i++){
int temp=A[left+i]
A[left+i]=A[right-i];
A[right-i]=temp;
}
}
void Exchange(int A[],int m,int n,int arraysize)
{
Reverse(A,0,m+n-1,arraysize);
Reverse(A,0,n-1,arraysize);
Reverse(A,n,n+m-1,arraysize)
}
oK,告一段落.