雙向鏈表基本操作以及優化可能


面試時面試官要求手寫雙向鏈表的 刪除操作,當時沒有考慮到邊界條件,導致被刷;
現在 列舉下代碼以及優化,作為事后反思:

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;
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM