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  间接删除
*/
时间: 2024-08-29 02:38:23

c++ 链表删除重复的数据的相关文章

CareerCup之2.1无序链表删除重复元素

[题目] 原文: 2.1 Write code to remove duplicates from an unsorted linked list. FOLLOW UP How would you solve this problem if a temporary buffer is not allowed? 译文: 从一个未排序的链表中移除重复的项 进一步地, 如果不允许使用临时的缓存,你如何解决这个问题? [分析] (1)如果可以使用额外的存储空间,我们就开一个数组来保存一个元素的出现情况.

删除重复的数据(完全一致的重复)

MSsql 遗留的数据表中存在大量重复的记录,这些重复的数据的特点是:包括标识ID在内,所有数据列都一样,即完全一致的重复.如何去掉重复的记录,例如2条相同的数据 ,ID,各个字段都完全相同,无法在现有数据 上把这两条数据 区分开,需要可以分别开来的字段, 具体步骤如下: --1 添加临时标识字段 1 alter table [表名] 2 add idd varchar(50) --2 更新此字段,这样就能区分数据 1 update [表名] set idd=NEWID() --3删除重复的,通

ORACLE 删除重复的数据

内容转自:https://www.cnblogs.com/zfox2017/p/7676237.html 查询及删除重复记录的SQL语句 1.查找表中多余的重复记录,重复记录是根据单个字段(Id)来判断 select Id from 表 group byId having count(Id) > 1  --(查找表中那个字段是重复的) select * from 表 where Id in (select Id from 表 group byId having count(Id) > 1) 

C++中删除重复的数据并且输出(相当与shell脚本里面的sort -u)

//问题: //给你一个数组,a[]={1,1,1,1,1,2,2,2,2,3,3,3,4,5,6} //要输出的结果是1,2,3,4,5,6.(去除重复的数字,要求时间空间的考虑). #include <iostream> using namespace std; struct Node { int data; Node *next; Node():data(-1),next(NULL){} }; //时间复杂度大幅度减少,但是增加了一定的空间复杂度. class Hash { public

mysql 中删除重复字段数据的方式

1.创建一张表 CREATE TABLE `user` ( `id` int(11) DEFAULT NULL, `name` varchar(255) DEFAULT NULL, `age` int(11) DEFAULT NULL, `address` varchar(255) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 2.插入对应数据 INSERT INTO `user` VALUES ('1', 'zhangsan', '20'

链表有环判断,快慢指针两种方法/合并链表/删除重复元素/二分递归和while

public static boolean hasCycle(ListNode head) { if (head == null || head.next == null) { return false; } ListNode slow = head; ListNode fast = head.next; while (slow != fast) { if (slow.next == null) return false; slow = slow.next; if (fast.next == n

mysql如何快速删除重复的数据

在mysql中去重,其实是一个很简单的事情,来看下面的例子: mysql> DROP TABLE test; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE test ( id  INT, NAME VARCHAR(10) ); Query OK, 0 rows affected (0.01 sec) mysql> INSERT INTO test VALUES(1,'a1'),(2,'a2'),(3,'a3'),(4,'

删除重复的数据

原文地址:https://www.cnblogs.com/igoodful/p/8964759.html

p108 有序链表删除重复节点(leetcode 82)

一:解题思路 Time:O(n),Space:O(1) 二:完整代码示例 (C++版和Java版) C++: class Solution { public: ListNode* deleteDuplicates(ListNode* head) { ListNode* dummy = new ListNode(0); dummy->next = head; ListNode* prev = dummy; ListNode* cur = prev->next; while (cur!=NULL)