单链表实现:交,并,差运算

BYH_Hecker 2008-12-17 01:10:20
小弟我刚刚完成了一个单链表,但是想在上面实现:交,并,差运算
不知道如何下手

#include <iostream>
using namespace std;

struct node{
int data;
struct node *next;
node(int d=0,node *nx=NULL):data(d),next(nx){}
};

struct link{
link():head(NULL),tail(NULL){}
~link(){
node *t=head;
while(t){
node *p=t;
t=t->next;
delete p;
}
head=tail=NULL;
}
void empty(){
if(tail==NULL){
cout<<"this is a empty list"<<endl;
}
else
cout<<"this is not empty list"<<endl;
}

//在尾部插入元素
void push_back(int v){
if(!tail)
head=tail=new node(v);
else{
tail->next=new node(v);
tail=tail->next;
}
}
//在inder位置插入某个元素
void insert(int index,int val){
node *t=head;
for(int i=0;i!=index-1;i++)
t=t->next;
node *s=new node(val);
s->next=t->next;
t->next=s;
}

//删除一个元素
void erase(int index){
node *t=head,*p;
for(int i=0;i!=index;i++){
t=t->next;
}
if(t==NULL) return;
else{
p=t->next;
t->next=p->next;
delete p;
}
}
//删除一段元素
void erase(int beg,int end){
node *s=head;
for(int i=0;i!=beg;i++){
s=s->next;
}
node *t=head;
for(int j=0;j!=end;j++){
t=t->next;
}
if(t==NULL||s==NULL) return;
else{
s->next=t->next;
}
}

//删除头元素(出队)
void pop_front(){
node *t=head;
if(head==tail)
head=tail=NULL;
else
head=head->next;
delete t;
}
//获得首元素
int get_front(){
return head->data;
}
//获得尾元素
int get_back(){
return tail->data;
}
//查找指定地址元素
int get_value(int index){
int i=0;
node *t=head;
while(i<index&&t!=NULL){
t=t->next;
i++;
}
if(t==NULL) return 0;
else return t->data;
}
//按元素查找第一次出现的地址
int get_idex(int val){
node *t=head;
int i=0;
while(t!=NULL&&t->data!=val){
i++;
t=t->next;
}
if(t==NULL) return 0;
return i;
}

void display(){
node* cur = head;
while (cur) {
cout<<cur->data;
cur = cur->next;
if (cur)
cout<<" -> ";
}
cout<<endl;
}
node *head;
node *tail;

};
还请高手请教,小弟不胜感激
...全文
620 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
l00106464 2009-02-12
  • 打赏
  • 举报
回复
LinkList merge(LinkList ha,LinkList hb)
{
LNode *pa,*pb,*pc;
LinkList hc = (LNode *)malloc(sizeof(LNode));
pa = ha;
pb = hb;
pc = hc;
while(pa!=NULL && pb!=NULL)
{
if(pa->data<pb->data)
{
pc->next = pa;
pc = pa;
pa = pa->next;
}
else if(pa->data>pb->data)
{
pc->next = pb;
pc = pb;
pb = pb->next;
}
else
{
pc->next = pb;
pc = pb;
pb = pb->data;
pc->next = pa;
pc = pa;
pa = pa->next;
}
pc->next = NULL;
}
while(pa!=NULL)
{
pc->next = pa;
pa = pa->next;
}
while(pb!=NULL)
{
pc->next = pb;
pb = pb->next;
}
hc = hc->next;
free(pc);
return hc;
}
yangkunhenry 2008-12-17
  • 打赏
  • 举报
回复

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define LEN sizeof(struct Nodeple)
typedef struct Nodeple
{
int i;
struct Nodeple *next;
}Node;

Node *creat(void)
{
int n=0;
Node *p1=(Node*)malloc(LEN);
Node *p2=(Node*)malloc(LEN);
Node *head;
printf("Please input the node:\n");
scanf("%d",&p1->i);
while(p1->i!=0)
{
n++;
if(n==1)
head=p1;
else
p2->next=p1;
p2=p1;
p1=(Node*)malloc(LEN);
scanf("%d",&p1->i);
}
p2->next=NULL;
free(p1);
p1=NULL;
return head;
}
void Print(Node* head)
{
Node * p;
p=head;
if(head!=NULL)
do
{
printf("%d-->",p->i);
p=p->next;
}while(p!=NULL);
printf("\n");
}
Node* mergAction(Node* head1,Node *head2)//合并
{
Node *p=NULL;
if(head1==NULL&&head2==NULL)
return p;
else if(head1==NULL)
return head2;
else if(head2==NULL)
return head1;
else
{
if(head1->i <= head2->i)
{
p = head1;
if(head1->i < head2->i)
{
p->next = mergAction(head1->next,head2);
}
else
{
p->next = mergAction(head1->next,head2->next);
}
}
else
{
p=head2;
p->next=mergAction(head1,head2->next);
}
return p;
}
}
int main()
{
Node *p=NULL;
Node *head1=creat();
Node *head2=creat();
p=mergAction(head1,head2);
Print(p);
return 0;
}
Please input the node:
1 3 4 5 0
Please input the node:
2 4 5 7 0
1-->2-->3-->4-->5-->7-->
Press any key to continue

并的!前几天刚写过……
ysuliu 2008-12-17
  • 打赏
  • 举报
回复
对的,所以我认为应该先排序,可以达到一劳永逸的效果。。

当然如果直接使用stl的list就什么问题都没有了。。


[Quote=引用 16 楼 Chiyer 的回复:]
引用 13 楼 ysuliu 的回复:
时间复杂度有点高啊。。交和差的时候对list1每个元素都要遍历list2一次。。

还有并的实现有问题啊,相同元素没有判断,而且没有排序。。



交和差的时候对list1每个元素都要遍历list2一次

------

在两者都是 无序 的情况下,似乎没有更好的方法
如果两者都是sorted 的,那就好办,象stl里的
set_intersection 都是基于已经sorted 的容器的

看实际情况,或许可以考虑先…
[/Quote]
xtting_8984313 2008-12-17
  • 打赏
  • 举报
回复
星宇哥的效率不是太好啊O(n^2)
不过lz的要求本来就有点.....,为何对链表要求这种操作呢,或许转换为排序的数组之后再考虑这种操作,如果经常使用的化。
星羽 2008-12-17
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 ysuliu 的回复:]
时间复杂度有点高啊。。交和差的时候对list1每个元素都要遍历list2一次。。

还有并的实现有问题啊,相同元素没有判断,而且没有排序。。

[/Quote]

交和差的时候对list1每个元素都要遍历list2一次

------

在两者都是 无序 的情况下,似乎没有更好的方法
如果两者都是sorted 的,那就好办,象stl里的
set_intersection 都是基于已经sorted 的容器的

看实际情况,或许可以考虑先排序
BYH_Hecker 2008-12-17
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 Chiyer 的回复:]
时间有限,只是给你参考,先实现功能在去修改和优化一下吧:)

其实,你可以用std::list stl提供里相应的交,并,差等算法
[/Quote]

多谢
星羽 2008-12-17
  • 打赏
  • 举报
回复
时间有限,只是给你参考,先实现功能在去修改和优化一下吧:)

其实,你可以用std::list stl提供里相应的交,并,差等算法
ysuliu 2008-12-17
  • 打赏
  • 举报
回复
时间复杂度有点高啊。。交和差的时候对list1每个元素都要遍历list2一次。。

还有并的实现有问题啊,相同元素没有判断,而且没有排序。。

[Quote=引用 9 楼 Chiyer 的回复:]
C/C++ code
#include <iostream>
using namespace std;

struct node{
int data;
struct node *next;
node(int d=0,node *nx=NULL):data(d),next(nx){}
};

struct link{
link():head(NULL),tail(NULL){}
~link(){
node *t=head;
while(t){
node *p=t;
t=t->next;
delete p;
}
head=tail=NULL;
}
void e…
[/Quote]
GreaterHeat 2008-12-17
  • 打赏
  • 举报
回复
链表实现交,并,差没什么实际意义。
难道去比较链表的每个节点存储的值?
链表中每个元素不要求有序。
BYH_Hecker 2008-12-17
  • 打赏
  • 举报
回复
星羽哥的求并集的时候若是把重复的数字去掉就好了

我自己试试,谢谢
BYH_Hecker 2008-12-17
  • 打赏
  • 举报
回复
一看见星羽哥的ID我马上进来了,就是牛
星羽 2008-12-17
  • 打赏
  • 举报
回复

#include <iostream>
using namespace std;

struct node{
int data;
struct node *next;
node(int d=0,node *nx=NULL):data(d),next(nx){}
};

struct link{
link():head(NULL),tail(NULL){}
~link(){
node *t=head;
while(t){
node *p=t;
t=t->next;
delete p;
}
head=tail=NULL;
}
void empty(){
if(tail==NULL){
cout <<"this is a empty list" <<endl;
}
else
cout <<"this is not empty list" <<endl;
}

//在尾部插入元素
void push_back(int v){
if(!tail)
head=tail=new node(v);
else{
tail->next=new node(v);
tail=tail->next;
}
}
//在inder位置插入某个元素
void insert(int index,int val){
node *t=head;
for(int i=0;i!=index-1;i++)
t=t->next;
node *s=new node(val);
s->next=t->next;
t->next=s;
}

//删除一个元素
void erase(int index){
node *t=head,*p;
for(int i=0;i!=index;i++){
t=t->next;
}
if(t==NULL) return;
else{
p=t->next;
t->next=p->next;
delete p;
}
}
//删除一段元素
void erase(int beg,int end){
node *s=head;
for(int i=0;i!=beg;i++){
s=s->next;
}
node *t=head;
for(int j=0;j!=end;j++){
t=t->next;
}
if(t==NULL||s==NULL) return;
else{
s->next=t->next;
}
}

//删除头元素(出队)
void pop_front(){
node *t=head;
if(head==tail)
head=tail=NULL;
else
head=head->next;
delete t;
}
//获得首元素
int get_front(){
return head->data;
}
//获得尾元素
int get_back(){
return tail->data;
}
//查找指定地址元素
int get_value(int index){
int i=0;
node *t=head;
while(i <index&&t!=NULL){
t=t->next;
i++;
}
if(t==NULL) return 0;
else return t->data;
}
//按元素查找第一次出现的地址
int get_idex(int val){
node *t=head;
int i=0;
while(t!=NULL&&t->data!=val){
i++;
t=t->next;
}
if(t==NULL) return 0;
return i;
}

bool has(int data)
{
node* cur = head;
while (cur)
{
if (cur->data == data)
return true;
cur = cur->next;
}
return false;
}

void display(){
node* cur = head;
while (cur) {
cout <<cur->data;
cur = cur->next;
if (cur)
cout <<" -> ";
}
cout <<endl;
}

node *head;
node *tail;

};

// 交
link* intersection(link* link1, link* link2)
{
link* new_link = new link;

node* cur = link1->head;
while (cur)
{
if (link2->has(cur->data))
new_link->push_back(cur->data);
cur = cur->next;
}

return new_link;
}

// 并
link* combine(link* link1, link* link2)
{
link* new_link = new link;

node* cur = link1->head;
while (cur)
{
new_link->push_back(cur->data);
cur = cur->next;
}

cur = link2->head;
while (cur)
{
new_link->push_back(cur->data);
cur = cur->next;
}

return new_link;
}

// 差
link* difference(link* link1, link* link2)
{
link* new_link = new link;

node* cur = link1->head;
while (cur)
{
if (!link2->has(cur->data))
new_link->push_back(cur->data);
cur = cur->next;
}

return new_link;
}

int main()
{
link* link1 = new link;
link* link2 = new link;

for (int i = 0; i < 10; ++i)
{
link1->push_back(i);
link2->push_back(i + 5);
}

cout<<"link 1 :";
link1->display();

cout<<"link 2 :";
link2->display();

link* inter = intersection(link1, link2);
cout<<"交 :";
inter->display();

link* comb = combine(link1, link2);
cout<<"并 :";
comb->display();

link* diff = difference(link1, link2);
cout<<"差 :";
diff->display();

delete link1;
delete link2;
delete comb;
delete inter;
delete diff;
return 0;
}


------------


link 1 :0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9
link 2 :5 -> 6 -> 7 -> 8 -> 9 -> 10 -> 11 -> 12 -> 13 -> 14
交 :5 -> 6 -> 7 -> 8 -> 9
并 :0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 5 -> 6 -> 7 -> 8 -> 9 -> 1
0 -> 11 -> 12 -> 13 -> 14
差 :0 -> 1 -> 2 -> 3 -> 4
请按任意键继续. . .
liusichen_0 2008-12-17
  • 打赏
  • 举报
回复
晚上回去看看
ysuliu 2008-12-17
  • 打赏
  • 举报
回复
这个有点麻烦,因为用你的链表实现起来效率是很低的,众所周知,链表不支持随机访问。。

我觉得你应该首先提供排序算法,使你的链表有序。。
两个有序链表再进行交并差运算就应该相对比较容易了。。

关于排序算法的实现,你可以参考stl中list::sort(),那是一个相当精巧的算法,效率很高,虽然有点耗费空间~
google一下就能找到源码.
BYH_Hecker 2008-12-17
  • 打赏
  • 举报
回复
例如:链表A a->b->c->e
链表C d->e>f->h
则A并B为 a->b->c->d->e->f->h(有排序)
nullah 2008-12-17
  • 打赏
  • 举报
回复
up
SearchLife 2008-12-17
  • 打赏
  • 举报
回复
MARK
baifanmvp 2008-12-17
  • 打赏
  • 举报
回复
就是啊 说清楚啊
yellowhwb 2008-12-17
  • 打赏
  • 举报
回复
以链表为基础的数据结构一般有heap,stack,tree,还有排序链表等
比如stack一般的操作有push,pop,清空操作等
还有一些排序算法,好像没听说过什么交、并、差运算!
jiww03 2008-12-17
  • 打赏
  • 举报
回复
什么交并差?是两个链表之间的吗?

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧