zoukankan      html  css  js  c++  java
  • c++ 链表删除重复的数据

    //List.h

    #include <iostream>
    typedef int dataType;
    
    struct Node{
        Node():data(0),pNextNode(NULL){} //结点构造函数
        dataType data;
        Node* pNextNode;
    };
    class List{
    private:
        Node *head; //作为链表唯一的头指针
        int size;   //链表长度
    public:
        List(){head=new Node;size=0;}
        bool isEmpty();                //判断是否空表
        bool InsertList(int i,dataType elem);  //i的指标从1开始,而不是从0开始
        void PushList(dataType elem);          //在链表尾部添加元素
        bool DeleteList(int i);        //删除指定位置的元素
        void ClearList();            //清除整条链表
        void DeleteRepetitiveData();//删除重复元素
        void PrintList();            //按顺序输出链表
        int GetSize();    
        Node* Fine(int i);            //找到第i个结点并返回该结点的指针
        Node* FinePre(int i);        //找到第i个结点前的结点,返回指针
    };

    //List.cpp

    #include "List.h"
    #include <iostream>
    #include <vector>
    using namespace std;
    //判断空表
    bool List::isEmpty(){
        if(head==NULL)
            return false;
        else
            return true;
    }
    //在第i位插入数据
    bool List::InsertList(int i,dataType elem){
        if (i<1)
            return false;
        else if(head==NULL||i==1)//如果是空表
        {
            head->data=elem;
            size++;
            return true;
        }
        else if (i>size)        //位标大于链表长度时,在尾部添加
        {
            PushList(elem);
            return true;
        }
        else
        {
            Node *pre=Fine(i-1);
            Node *follow=Fine(i);
            Node *s=new Node;        //为新结点申请内存
            pre->pNextNode=s;        //连接前结点
            s->pNextNode=follow;    //连接后结点
            s->data=elem;
            size++;
            return true;
        }
    }
    //在尾部添加元素
    void List::PushList(dataType elem){
        if(head==NULL)
        {
            head=new Node;
            head->data=elem;
            size++;
        }
        else
        {
            Node *cur=head;
            while(cur->pNextNode)
                cur=cur->pNextNode;
            Node *s=new Node;
            cur->pNextNode=s;
            s->data=elem;
            size++;
        }
    }
    //打印链表
    void List::PrintList(){
        Node *cur=head;
        while (cur!=NULL)
        {
            cout<<cur->data<<"  ";
            cur=cur->pNextNode;
        }
        cout<<endl;
    }
    //size
    int List::GetSize(){
        return size;
    }
    //找到第i个结点
    Node* List::Fine(int i){
        if(i==1)
            return head;
        else
        {
            Node *cur=head;
            for (int pos=1;pos<i;pos++)
                cur=cur->pNextNode;
            return cur;
        }    
    }
    //找到i的前一个个结点
    Node* List::FinePre(int i){
        if(i<2)
        {
            cout<<"参数必须大于等于2!"<<endl;
            return NULL;
        }
        else if(i==2)
            return head;
        else
            return Fine(i-1);
    }
    //删除第i个元素
    bool List::DeleteList(int i){
        if (i<1||i>size)        //限制i的范围
            return false;
        else if(i==1)
        {
            Node *temp=head;
            head=head->pNextNode;
            delete temp;
            size--;
            return true;
        }
        else
        {
            Node *cur=this->Fine(i);
            Node *pre=this->FinePre(i);
            pre->pNextNode=cur->pNextNode; //重新连接结点
            delete cur;
            size--;
            return true;
        }
    }
    //清空整个链表
    void List::ClearList(){
        Node *temp=head;
        while (head!=NULL)
        {
            temp=head;
            head=head->pNextNode;
            delete temp;
        }
        size=0;
    }
    //删除重复元素
    void List::DeleteRepetitiveData(){
        int flag=0;        //代码运行标志,0为未运行
        if(size==1)        //只有一个元素时跳出
            return;
        Node *stand=head;//内循环结束后或者找到相同数据后才会指向下个结点
        Node *cursor;    //游标
        vector<int>storge;
        for (int i=0;i<size;i++)
        {            //用for循环是因为要得到被删除元素的位置
                    //采用握手式比较,算法的时间复杂度为O(n^2)
            cursor=stand->pNextNode;
            flag=0;
            while(cursor!=NULL)
            {
                if(stand->data==cursor->data)
                {
                    stand=stand->pNextNode;
                    flag=1;
                    //将重复的数据的下标降序保存起来
                    storge.insert(storge.begin(),i+1);
                    break;
                }
                else
                    cursor=cursor->pNextNode;
            }    
            if(!flag)
                stand=stand->pNextNode;
        }
        int itemp=storge.size();
        while (itemp--)        
        {
            this->DeleteList(storge.at(0));//提取下标,释放多余结点
            storge.erase(storge.begin());
        }
        storge.clear();    //释放vector内存
    }

    //main.cpp

    #include "List.h"
    #include <iostream>
    using namespace std;
    
    void main(){
        //List类测试代码
        List list;
        list.InsertList(1,1);
        list.InsertList(5,3);
        list.InsertList(2,2);
        list.InsertList(4,4);    
        list.PrintList();        //打印这4个元素
        cout<<"链表的长度为:"<<list.GetSize()<<endl;
        cout<<"现在删除第2个元素"<<endl;
        list.DeleteList(2);        
        list.PrintList();        
        cout<<"现在清空链表"<<endl;
        list.ClearList();        //清空链表
        cout<<"输出空表:"<<endl;
        list.PrintList();        
        
        list.PushList(4);
        list.PushList(1);
        list.PushList(7);
        list.PushList(1);
        list.PushList(1);
        list.PushList(2);
        list.PushList(2);        //压入4 1 7 1 1 2 2
        cout<<"输出链表新加入的元素:"<<endl;    
        list.PrintList();
        cout<<"删除相同元素后的链表为:"<<endl;    
        list.DeleteRepetitiveData();
        list.PrintList();
    }
    
    /*
    总结:
    1.链表类应该先写Fine()和FindPre(),再写插入和删除
    2.链表的结构应该给每一个结点加上一个下标。因为下标在
      操作时再加上的话,元素跟下标是不统一的,
      如果有元素被删除,下标将要重新分配。
     这就导致
    void List::DeleteRepetitiveData()不能用
     相对直接的方法在检测到重复数据时就删除数据,而要借助vector
    间接删除
    */
  • 相关阅读:
    修复PLSQL Developer 与 Office 2010的集成导出Excel 功能
    Using svn in CLI with Batch
    mysql 备份数据库 mysqldump
    Red Hat 5.8 CentOS 6.5 共用 输入法
    HP 4411s Install Red Hat Enterprise Linux 5.8) Wireless Driver
    变更RHEL(Red Hat Enterprise Linux 5.8)更新源使之自动更新
    RedHat 5.6 问题简记
    Weblogic 9.2和10.3 改密码 一站完成
    ExtJS Tab里放Grid高度自适应问题,官方Perfect方案。
    文件和目录之utime函数
  • 原文地址:https://www.cnblogs.com/zoffy/p/4009717.html
Copyright © 2011-2022 走看看