二叉树的高度 、销毁、链表的翻转(k为一组、n-m 之间)两种实现、

来源:互联网 发布:seo网站关键词优化 编辑:程序博客网 时间:2024/06/15 16:36

1.二叉树的高度:

//实现思路:左右子树较高的一支,将其结果结+1就是当前树的高度size_t GetHeight(Node* pRoot){    if (pRoot)    {        size_t left = GetHeight(pRoot->pLeft);        size_t right= GetHeight(pRoot->pRight);        return left > right ? left + 1 : right + 1;    }

2.二叉树的销毁

//实现思路:后序遍历,进行销毁void Destroy(Node*& pRoot) //参数最好给引用,方便直接修改外部参数为NULL{    if (pRoot)    {        Destroy(pRoot->pLeft);        Destroy(pRoot->pRight);        delete pRoot;        pRoot = NULL;    }}

3.链表的翻转(以k为一组)

//以K为单位翻转链表//思路:两种实现思路:1.递归法2.迭代法//递归出口,如果链表长度小于//实现区间内的链表翻转,并且返回翻转后的头结点//内部调用自己,将返回结果善加利用Node* reversekGroup1(Node* head, int k){    if (head == NULL || head->pNext == NULL || k < 2)    {        return head;    }    Node* next_group = head;    for (int i = 1; i < k; i++)  //走k-1步    {        if (next_group)        {            next_group = next_group->pNext;        }        else        {            return head;   //长度小于K  ,直接返回头结点        }    }    Node* new_next_group = reversekGroup1(next_group,k);//返回下一组的头结点    Node* prev = NULL, *cur = head;    while (cur != next_group)// 实现翻转:翻转三要素:三个指针,保存下一个指针,就可以自由操作了    {        Node* next = cur->pNext;        cur->pNext = prev ? prev : new_next_group;        prev = cur;        cur = next;    }    return prev;   //prev will be the new head of this group}//prev为 first的前一个元素,[begin ,end] 闭区间,保证三者都不为NULL//返回翻转后的倒数第一个元素//实现翻转Node* reverse(Node* prev, Node* begin, Node* end){    Node* end_next =end->pNext;    for (Node* p = begin, *cur = p->pNext, *next = cur->pNext;        cur != end_next;        p = cur, cur = next, next = next ? next->pNext : NULL        )    {        cur->pNext = p;    }    begin->pNext = end_next;    prev->pNext = end;    return begin;}//迭代法:思路:每K个区间翻转一次,实现整体翻转Node* reversekGroup2(Node* head, int k){    if (head == NULL || head->pNext == NULL || k < 2)    {        return head;    }    Node dummy(-1);   //因为头结点会发生改变,所以虚拟头结点可以有效的解决该问题    dummy.pNext = head;    for (Node* prev = &dummy, *end = head; end; end = prev->pNext)    {        //每K个划分为一组        for (int i = 0; i < k&&end; i++)        {            end = end->pNext;        }        if (end == NULL)        {            break;   //不足K个        }        prev = reverse(prev,prev->pNext,end);    }    return dummy.pNext;}void Test1(){    Node* node1 = new Node(1);    Node* node2 = new Node(2);     Node* node3 = new Node(3);    Node* node4 = new Node(4);    Node* node5 = new Node(5);    Node* node6 = new Node(6);    Node* node7 = new Node(7);    Node* node8 = new Node(8);    Node* node9 = new Node(9);    Node* node10 = new Node(10);    node1->pNext = node2;    node2->pNext = node3;    node3->pNext = node4;    node4->pNext = node5;    node5->pNext = node6;    node6->pNext = node7;    node7->pNext = node8;    node8->pNext = node9;    node9->pNext = node10;    //ReverseEveryKth(node1, 2);    //reverBetween(node1,2,4);    Print(node1);    cout << endl;    /*Node* temp=reversekGroup1(node1, 3);    Print(temp);    cout << endl;*/    Node* temp = reversekGroup2(node1, 3);    Print(temp);}

4.链表的翻转(n-m之间)

//将n-m之间的元素进行翻转//头插法实现Node* reverBetween(Node* head, int m, int n){    Node dummy(-1);    dummy.pNext = head;    Node* prev = &dummy;    for (int i = 0; i < m; i++)    {        prev = prev->pNext;    }    Node* head2 = prev;    prev = head2->pNext;    Node* cur = prev->pNext;    for (int i = m; i < n; i++)    {        //头插法        //三步翻转法(头结点始终不变,插入到头的下一个结点)        prev->pNext = cur->pNext;        cur->pNext = head2->pNext;        head2->pNext = cur;  //头插法        cur = prev->pNext;    }    return dummy.pNext;}
阅读全文
0 0