首页 > 代码库 > c++ 链表删除重复的数据
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=http://www.mamicode.com/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=http://www.mamicode.com/elem; size++; return true; }}//在尾部添加元素void List::PushList(dataType elem){ if(head==NULL) { head=new Node; head->data=http://www.mamicode.com/elem; size++; } else { Node *cur=head; while(cur->pNextNode) cur=cur->pNextNode; Node *s=new Node; cur->pNextNode=s; s->data=http://www.mamicode.com/elem; size++; }}//打印链表void List::PrintList(){ Node *cur=head; while (cur!=NULL) { cout<<cur->data<<" "; cur=cur->pNextNode; } cout<<endl;}//sizeint 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=http://www.mamicode.com/=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
间接删除
*/
c++ 链表删除重复的数据
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。