手写链表二叉树队列

Posted fangzheng-nie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手写链表二叉树队列相关的知识,希望对你有一定的参考价值。

// 反转单链表  
ListNode * ReverseList(ListNode * pHead)  
{  
        // 如果链表为空或只有一个结点,无需反转,直接返回原链表头指针  
    if(pHead == NULL || pHead->next == NULL)    
        return pHead;  
  
    ListNode * pReversedHead = NULL; // 反转后的新链表头指针,初始为NULL  
    ListNode * pCurrent = pHead;  
    while(pCurrent != NULL)  
    {  
        ListNode * pTemp = pCurrent;  
        pCurrent = pCurrent->next;  
        pTemp->next = pReversedHead; // 将当前结点摘下,插入新链表的最前端  
        pReversedHead = pTemp;  
    }  
    return pReversedHead;  
}  

查找单链表中间节点

设置两个指针,只不过这里是,两个指针同时向前走,前面的指针每次走两步,后面的指针每次走一步,前面的指针走到最后一个结点时,后面的指针所指结点就是中间结点,即第(n/2+1)个结点。注意链表为空,链表结点个数为1和2的情况。时间复杂度O(n)。参考代码如下:

// 获取单链表中间结点,若链表长度为n(n>0),则返回第n/2+1个结点  
ListNode * GetMiddleNode(ListNode * pHead)  
{  
    if(pHead == NULL || pHead->next == NULL) // 链表为空或只有一个结点,返回头指针  
        return pHead;  
  
    ListNode * pA = pHead;  
    ListNode * pB = pHead;  
    while(pA->next != NULL) // 前面指针每次走两步,直到指向最后一个结点,后面指针每次走一步  
    {  
        pA = pA->next;  
        pB = pB->next;  
        if(pA->next != NULL)  
            pA = pA->next;  
    }  
    return pB; // 后面的指针所指结点即为中间结点  
}  

合并两个有序的单链表使之有序

ListNode * MergeSortedList(ListNode * pHead1, ListNode * pHead2)  
{  
    if(pHead1 == NULL)  
        return pHead2;  
    if(pHead2 == NULL)  
        return pHead1;  
    ListNode * pHeadMerged = NULL;  
    if(pHead1->data < pHead2->data)  
    {  
        pHeadMerged = pHead1;  
        pHeadMerged->next = MergeSortedList(pHead1->next, pHead2);  
    }  
    else  
    {  
        pHeadMerged = pHead2;  
        pHeadMerged->next = MergeSortedList(pHead1, pHead2->next);  
    }  
    return pHeadMerged;  
}  

单链表第一个公共节点

ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2)
 {        
         ListNode *p1 = pHead1;
        
         ListNode *p2 = pHead2;
        
       while(p1!=p2)
       {
            
            p1 = (p1==NULL ? pHead2 : p1->next);
            
            p2 = (p2==NULL ? pHead1 : p2->next);
        }
        
         return p1;
}

更多单链表请移步:https://blog.csdn.net/u014800094/article/details/69523799

==========================================

  树的广度优先遍历。BFS,也就是层次遍历,相当于前序。需要借助一个队列,现将二叉树的根节点入队,然后出队,访问该节点,如果它有左子树,则将左子树根节点入队;如果有右子树,则将右子树根节点入队。然后出队,对出队节点访问,如此反复,直到队列为空。

 

void LevelOrder(BiTree root)
{
     InitQueue(Q);               //初始化队列
    
     BiTree p;
     EnQueue(Q,root);            //将根节点入队
     while(!IsEmpty(Q))          //队列不空循环
     {
         DeQueue(Q,p);          //访问p所指向节点
         visit(p);
        if(p->lchild != NULL)
              EnQueue(Q,p->lchild);         //左子树不空则左子树入队
        if(p->rchild != NULL)
              EnQueue(Q,p->rchild);
      }
}

树的深度优先遍历。 DFS,遍历了根节点后,就开始遍历左子树,所以右子树肯定最后遍历。我们利用栈的性质,所以先将右子树压栈,然后在对左子树压栈。此时,左子树节点是在top上的,所以可以先去遍历左子树。

void DepthFirstTravel(BiTree *root)  
{  
    stack<BiTree *> s;  
     s.push(root);           //根节点入栈
    while(!s.empty())  
    {  
        root = s.top();                //读取根节点
            s.pop();                     //根节点出栈
 
        if(root->rchild != NULL)  
        {  
            s.push(root->rchild);           //先右
        }  
        if(root->lchild != NULL)  
        {  
            s.push(root->lchild);           //再左
        }  
  
    }  
}  

栈空: s.top ==  -1

栈满: s.top == MaxSize -1

入栈: s.data[++s.top] = x ;     //指针先加1,再入栈

出栈: x = s.data[s.top--];        //先出栈,指针再减1

 

队空:Q.front == Q.rear

队满:(Q.rear+1)%MaxSize == Q.front

队列中元素:(Q.rear - Q.front + Maxsize)%MaxSize

==========================
两个栈实现队列

12

void push(int node)
 {
       stack1.push(node);
 }
int pop()
 {
        int a;
        if(stack2.empty())
       {
            while(!stack1.empty())
            {
                a=stack1.top();
                stack2.push(a);
                stack1.pop();
            }
        }
        a=stack2.top();
        stack2.pop();
        return a;
         
 }

<分析>:

入队:将元素进栈A

出队:判断栈B是否为空,如果为空,则将栈A中所有元素pop,并push进栈B,栈B出栈;

 如果不为空,栈B直接出栈。

同理:

用两个队列实现一个栈的功能

<分析>:

入栈:将元素进队列A

出栈:判断队列A中元素的个数是否为1,如果等于1,则出队列,否则将队列A中的元素   以此出队列并放入队列B,直到队列A中的元素留下一个,然后队列A出队列,再把   队列B中的元素出队列以此放入队列A中。

以上是关于手写链表二叉树队列的主要内容,如果未能解决你的问题,请参考以下文章

java数据结构:二叉树

15 道二叉树手写算法题

[DataStructure]哈希表二叉树及多叉树 Java 代码实现

栈和队列----将搜索二叉树转换成双向链表

已知一颗二叉链表表示二叉树T ,编写函数,判断T是不是为完全二叉树。先

[DataStructure]非线性数据结构之哈希表二叉树及多叉树 Java 代码实现