zoukankan      html  css  js  c++  java
  • 数据结构基础(9) --单链表的设计与实现(2)之高级操作

    链表的链接:

        将第二条链表的所有内容链接到第一条链表之后, 其完整实现代码与解析如下:

    //链表的链接
    template <typename Type>
    void MyList<Type>::concatenate(const MyList<Type> &list)
    {
        if (isEmpty())//如果自己的链表为空
        {
            first = list.first;
            return ;
        }
        else if (list.isEmpty())    //如果第二条链表为空
        {
            return ;
        }
    
        Node<Type> *endNode = first->next;
        //找到第一条链表的末尾节点
        while (endNode->next != NULL)
        {
            endNode = endNode->next;
        }
    
        //找到第二条链表的第一个真实元素
        Node<Type> *secondListNode = (list.first)->next;
        //注意: 需要将第二个链表中的元素值copy出来
        //不能直接将第二条链表的表头链接到第一条链表的表尾
        //不然在析构函数回收内存时会发生错误(即:同一段内存释放两次)
        while (secondListNode != NULL)
        {
            Node<Type> *newNode = new Node<Type>(secondListNode->data);
            newNode->next = NULL;
            endNode->next = newNode;
    
            //两条链表同时前进
            endNode = endNode->next;
            secondListNode = secondListNode->next;
        }
    }

    链表的反转:

    基本思想:

        遍历一遍链表,利用一个辅助指针(此处为指针r),存储遍历过程中当前指针指向的下一个元素,然后将当前节点元素的指针反转后,利用已经存储的指针往后面继续遍历。

    //链表的反转
    template <typename Type>
    void MyList<Type>::invort()
    {
        if (!isEmpty())
        {
            //p指向正向链表的第一个真实节点
            //随后, p也会沿正方向遍历到链表末尾
            Node<Type> *p = first->next;
    
            //q会成为倒向的第一个真实节点
            //首先将q设置为NULL: 保证反向之后
            //最后一个元素的指针域指向NULL, 以表示链表结束
            Node<Type> *q = NULL;
            while (p != NULL)
            {
                Node<Type> *r = q;  //暂存q当前指向的节点
                //q后退(沿着正向后退)
                q = p;
                //p前进(沿着正向前进), 保证p能够始终领先q一个位置
                p = p -> next;
                //将指针逆向反转
                //注意:一点要保证这条语句在p指针移动之后运行,
                //不然p就走不了了...(因为q改变了指针的朝向)
                q -> next = r;
            }
    
            //此时q成为反向链表的第一个真实元素
            //但是为了维护像以前一样的first指针指向一个无用的节点(以使前面的操作不会出错)
            //于是我们需要将first的指针域指向q
            first->next = q;
        }
    }

    链表打印:

        重载MyList<<运算符输出链表所有元素以供测试之用

    //显示链表中的所有数据(测试用)
    template <typename Type>
    ostream &operator<<(ostream &os, const MyList<Type> &list)
    {
        for (Node<Type> *searchNode = list.first -> next;
                searchNode != NULL;
                searchNode = searchNode -> next)
        {
            os << searchNode -> data;
            if (searchNode -> next != NULL) //尚未达到链表的结尾
                cout << " -> ";
        }
    
        return os;
    }

    -测试代码:

    int main()
    {
        cout << "------------ 1 ------------" << endl;
        MyList<int> first;
        for (int i = 0; i < 5; ++i)
        {
            first.insert(i+1, i+1);
        }
        first.remove(5);
    
        MyList<int> second;
        for (int i = 0; i < 5; ++i)
        {
            second.insert(i+6, i+1);
        }
        second.insertFront(5);
        second.insert(88, 7);
    
        cout << "Before concatenate..." << endl;
        cout << "first: " << first << endl;
        cout << "second: " << second << endl;
    
        cout << "After concatenate..." << endl;
        first.concatenate(second);
        cout << "first: " << first << endl;
        cout << "second: " << second << endl;
    
    
        cout << "
    ------------ 2 ------------" << endl;
        MyList<char> chList;
        for (char ch = '0'; ch <= '9'; ++ ch)
        {
            chList.insertFront(ch);
        }
        cout << "Before invort..." << endl;
        cout << chList << endl;
    
        cout << "After invort..." << endl;
        chList.invort();
        cout << chList << endl;
    
        cout << "After remove('5')..." << endl;
        chList.remove('5');
        cout << chList << endl;
    
        cout << "
    ------------ 3 ------------" << endl;
        MyList<double> dList;
        dList.insert(1.1, 1);
        dList.insertFront(2.2);
        cout << dList << endl;
    
        return 0;
    }


  • 相关阅读:
    谈薪资
    测试工程师 技能要求:java编程,数据库,linux操作系统,自动化测试开发,性能测试,安全测试
    测试工程师 工作要求
    python有木有哪些必须要学习的高级模块
    jmeter 网速
    fiddler抓包https
    做性能测试时如何实时监测服务器或接口性能???
    [drp 3]读取Xml配置文件,连接数据库
    [drp 2]String、StringBuffer和StringBuilder的区别
    SQL 1:常用SQL语句
  • 原文地址:https://www.cnblogs.com/itrena/p/5926997.html
Copyright © 2011-2022 走看看