标签:两个指针 一个栈 手写 初始化 middle blog tree 直接 ddl
// 反转单链表 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中。
标签:两个指针 一个栈 手写 初始化 middle blog tree 直接 ddl
原文地址:https://www.cnblogs.com/fangzheng-nie/p/13236737.html