双向链表基本操作以及优化可能

面试时面试官要求手写双向链表的 删除操作,当时没有考虑到边界条件,导致被刷;
现在 列举下代码以及优化,作为事后反思:

C 版本:

双向链表的结构定义

typedefstruct doubleLink
{
int data;
struct doubleLink *prior;
struct doubleLink *suffix;
}DOUBLE_LINK;

  

创建一个双向链表

/*创建一个双链表*/
DOUBLE_LINK *createDoubleLink()
{
DOUBLE_LINK *head = NULL;
head =(DOUBLE_LINK*)malloc(sizeof*head);
head->prior = NULL;
head->suffix = NULL;
return head;
}

  

插入函数

/*插入节点*/
bool insertNode(DOUBLE_LINK*head,int data)
{
if(head == NULL)
returnfalse;
DOUBLE_LINK *currNodep = NULL;
DOUBLE_LINK *nextp = NULL;
DOUBLE_LINK *newNodep = NULL;
for(currNodep = head;(nextp = currNodep->suffix)!= NULL; currNodep = nextp)
{
if(nextp->data == data)
returnfalse;
if(nextp->data > data)
break;
}
newNodep =(DOUBLE_LINK*)malloc(sizeof*newNodep);
if(newNodep == NULL)
returnfalse;
newNodep->data = data;
#if 1
/*需要插入双向链表时,遍历到需要插入的位置,开始对待插入的节点,前驱指针和后驱指针赋值,
后驱指针固定指向下一个节点指针,前驱需要区分 前指针是否是 头节点。
再对 当前节点的前驱指针赋值,需要区分待插入的点是不是 尾节点*/
//1.当前节点的后驱指针
currNodep->suffix = newNodep;
//2.新节点的前驱指针
if(currNodep == head)
newNodep->prior = NULL;
else
newNodep->prior = currNodep;
//3.新节点的后驱指针
newNodep->suffix = nextp;
//4.下一个节点的前驱指针
if(nextp == NULL)//到了尾节点处,则将头节点的前驱指向该尾节点,这是双向链表的结构精髓所在
head->prior = newNodep;
else
nextp->prior = newNodep;
#else
if(nextp != NULL)
{
//one not in the tail
newNodep->suffix = nextp;
currNodep->suffix = newNodep;
if(currNodep != head)// not the head
{
newNodep->prior = currNodep;
}
else// currnode is head
{
newNodep->prior = NULL;
}
nextp->prior = newNodep;
}
else
{
//in the tail
currNodep->suffix = newNodep;
if(currNodep != head)//not the head
{
newNodep->prior = currNodep;
}
else//is the head
{
head->prior = newNodep;
newNodep->prior = NULL;
}
newNodep->suffix = NULL;
}
#endif
returntrue;
}

  

删除某个节点

/*删除某个节点*/
bool deleteNode(DOUBLE_LINK *head, DOUBLE_LINK *item)
{
_ASSERT(head != NULL);
_ASSERT(item != NULL);
DOUBLE_LINK *currentNodep = NULL;
DOUBLE_LINK *nextp = NULL;
for(currentNodep = head;(nextp = currentNodep->suffix)!= NULL; currentNodep = nextp)
{
if(nextp == item)
{
/*当前节点为头结点时,这一点很重要*/
if(currentNodep == head)// the head
{
currentNodep->prior = NULL;
currentNodep->suffix = nextp->suffix;
free(nextp);
nextp = NULL;
break;
}
//最后一个节点时
elseif(nextp->suffix == NULL)// the tail
{
currentNodep->suffix = NULL;
free(nextp);
nextp = NULL;
break;
}
else// the mid
{
DOUBLE_LINK *tmp = nextp->suffix;
currentNodep->suffix = nextp->suffix;
nextp->prior = currentNodep;
free(nextp);
nextp = tmp;
}
}
}
returntrue;
}

  

删除节点函数优化

bool deleteNode_opt(DOUBLE_LINK *head, DOUBLE_LINK *item)
{
_ASSERT(head != NULL);
_ASSERT(item != NULL);
//要删除第一个节点
if(item == head->suffix)
{
head->suffix = item->suffix;
item->suffix->prior = NULL;
}
//要删除最后一个节点
elseif(item == head->prior)
{
head->prior = item->prior;
item->prior->suffix = NULL;
}
else
{
item->prior->suffix = item->suffix;
item->suffix->prior = item->prior;
}
free(item);
item = NULL;
returntrue;
}

  

打印函数

void printAllNode(DOUBLE_LINK *head)
{
_ASSERT(head != NULL);
DOUBLE_LINK *currentNodep = NULL;
DOUBLE_LINK *nextNodep = NULL;
std::cout <<"Node data is: ";
for(currentNodep = head;(nextNodep = currentNodep->suffix)!= NULL; currentNodep = nextNodep)
{
std::cout << nextNodep->data<<" ";
}
std::cout << std::endl;
}

  

posted @ 2017-05-12 22:24  Lckfa  阅读(1569)  评论(0编辑  收藏  举报