c++ 链表

12 篇文章 1 订阅

一、问题描述

1、题目内容:集合的并、交和差运算

编写一个能演示执行集合的并、交和差运算的程序。

2、基本要求

由用户输入两组整数分别作为两个集合的元素,由程序计算它们的交、并和差集,并将运算结果输出。

3、测试数据

测试数据为两组正整数,范围最好在0~35000之间。

S1={3569122735}

S2={58101227312515563}

运行结果:

S1ÈS2={35689101227313542515563}, 

S1ÇS2={51227}

S1-S2={36935}

实现提示:

以有序链表表示正整数集合。

代码:

//2013-3-12


//list头文件

//合理的设置模式(隔离变化)

typedef int ElemType;

//定义结点
struct ListNode
{
	ElemType data;
	ListNode* next;
};


//定义链表类
//注意接口的粒度的合理性

class List
{
private:
	ListNode* m_head;//头指针
	ListNode* m_tail;//尾指针
	int m_length;//链表的结点数目

public:
	//
	List();
	//在链表的后面追加元素
	//重载该函数
	//值专递,方便输入
	//地址传递,提高效率
	void AppendNode(ListNode item);
	void AppendNode(ListNode* item);
	//清空链表
	void ClearList();
	//返回链表的长度
	int LengthList();
	//返回L中第index个元素
	//以0开始
	ListNode* GetList(int index);
	//遍历输出l中所有元素
	void TraverseList();
	//查找item元素,并在index中保存下标
	bool FindList(ListNode* item,int* index);
	//更新第index个元素
	bool UpdateList(int index,const ListNode item);
	//
	bool InsertList(ListNode* item,int index);
	//
	bool DeleteList(ListNode item);

	//
	void CopyList(List* list);
};

//2013-3-13

//list cpp

#include<iostream>

#include"List.h"

using namespace std;


//
//
//index 以0开始



//
List::List()
{
	m_head=m_tail=NULL;
	m_length=0;
}

//
//ok
void List::AppendNode(ListNode item)
{
	//在堆里分配的内存 
	ListNode* pitem=new ListNode(item);

		//如果链表为空
	if (m_head==NULL)
	{
		m_head=pitem;
		m_tail=pitem;
		++m_length;
	}else
	{
		//如果不为空
		m_tail->next=pitem;
		pitem->next=NULL;
		m_tail=pitem;
		++m_length;
	}

}

//ok
void List::AppendNode(ListNode* item)
{
	//如果链表为空
	if (m_head==NULL)
	{
		m_head=item;
		m_tail=item;
		++m_length;
	}else
	{
		//如果不为空
		m_tail->next=item;
		item->next=NULL;
		m_tail=item;//指针往后移
		++m_length;
	}


}



//ok
void List::ClearList()
{
	//从头到尾删除

	//
	//ListNode* pdelenode;

	如果链表为空,直接返回
	//if (m_head==NULL)
	//{
	//	return ;
	//}

	//do
	//{
	//	pdelenode=m_head;
	//	//指向下个结点
	//	m_head=m_head->next;

	//	//释放pdelenode指针指向的内存
	//	delete pdelenode;
	//}while (m_head!=m_tail);

	删除最后一个结点,并处理指针
	//m_head=m_tail=NULL;
	//m_lenth=0;
	//delete pdelenode;
	//pdelenode=NULL;
	ListNode* cp;
	ListNode* np;
	cp=m_head;
	while (cp!=NULL)
	{
		np=cp->next;
		delete cp;
		cp=np;
	}
	m_tail=m_head=NULL;
	m_length=0;

}


//
//ok
int List::LengthList()
{
	return m_length;
}


//0下标开始
//ok
ListNode* List::GetList(int index)
{
	int readindex=index-1;
	ListNode* finder;

	if (readindex>m_length)
	{
		cout<<"查找失败."<<endl;
		return NULL;
	}

	//first node
	if (readindex==0)
	{
		return m_head;
	}

	//last node
	if (readindex==(m_length-1))
	{
		return m_tail;
	}

	//else
	finder=m_head;
	for (int i = 1; i <= readindex; i++)
	{
		finder=finder->next;
	}
	return finder;
}

//
//ok
void List::TraverseList()
{
	ListNode* out=m_head;

	if (m_length!=0)
	{
		while (out!=NULL)
		{
			cout<<out->data<<" ";
			out=out->next;
		}
	}
}

//
//ok
bool List::FindList(ListNode* item,int* index)
{
	ListNode* currnode=m_head;
	int item_index=0;

	while ((currnode->data!=item->data)&&item_index++<m_length-1)
	{
		
		currnode=currnode->next;
		//++item_index; /debug
	}

	if (item_index>=m_length)
	{
		*index=-1;
		return false;
	}else
	{
		*index=item_index+1;
		return true;
	}
}

//ok
bool List::UpdateList(int index,const ListNode item)
{
	ListNode* updatenode=GetList(index);
	if (updatenode!=NULL)
	{
		updatenode->data=item.data;
		return true;
	}
	return false;
}

//2013-3-14
//
// 在链表不为空的前提下
//ok
bool List::InsertList(ListNode* item,int index)
{
	//找到将要插入的前一项 
	ListNode* previtem=GetList(index);

	if (previtem==NULL)
	{
		cout<<"插入失败。"<<endl;
		return false;
	}

	//item指向previtem的下一个元素
	item->next=previtem->next;

	//previtem指向item
	previtem->next=item;

	previtem=item=NULL;
	//长度+1
	++m_length;

	return true;
}

//
//ok
bool List::DeleteList(ListNode item)
{
	//将要删除的元素的前驱变量
	ListNode* prevdelenode=m_head;

	//要删除的元素的指针
	ListNode* delenode=m_head;

	//
	while ((delenode->data!=item.data)&&delenode!=NULL)
	{
		prevdelenode=delenode;
		delenode=delenode->next;
	}

	if (delenode==NULL)
	{
		cout<<"不存在该元素。"<<endl;
		return false;
	}

	//如果是删除第一个
	if (delenode==m_head)
	{
		prevdelenode=NULL;
		m_head=m_head->next;
		delete delenode;
		--m_length;
		return true;
	}

	//如果是删除最后一个
	if (delenode==m_tail)
	{
		m_tail=prevdelenode;
		m_tail->next=NULL;

		prevdelenode=NULL;

		delete delenode;
		--m_length;
		return true;
	}

	//prevdelenode指向delenode的下个元素
	prevdelenode->next=delenode->next;
	//
	delenode->next=NULL;
	//
	delete delenode;
	//
	--m_length;

	return true;


}

//
//ok
void List::CopyList(List* list)
{
	ListNode node={NULL,NULL};
	ListNode* datanode=list->m_head;
	while (datanode!=NULL)
	{
		node.data=datanode->data;
		AppendNode(node);
		datanode=datanode->next;
	}

}
//
//2013-3-14

#include<iostream>

#include"List.h"

using namespace std;





int main()
{
	List set1;
	List set2;

	List add_set;//并集
	List same_set;//交集
	List cut_set;//差集

	ListNode node={NULL,NULL};
	cout<<"请输入set1的数值,以-1结束。"<<endl;
	while (cin>>(node.data),(node.data)!=-1)
	{
		set1.AppendNode(node);
	}


	cout<<"请输入set2的数值,以-1结束。"<<endl;
	while (cin>>(node.data),(node.data)!=-1)
	{
		set2.AppendNode(node);
	}

	//将set1复制到三个集合
	add_set.CopyList(&set1);
	same_set.CopyList(&set1);
	cut_set.CopyList(&set1);

	//int set2_data=NULL;
	ListNode set2_node={NULL,NULL},set1_node={NULL,NULL};
	int nothing=0;//作为函数参数引用
	//遍历set2集合
	for (int i = 1; i <= set2.LengthList(); i++)
	{

		set2_node.data=set2.GetList(i)->data;

		//add_set
		if (!add_set.FindList(&set2_node,¬hing))//NULL=worng
		{
			add_set.AppendNode(set2_node);
		}

		//cut_set
		if (cut_set.FindList(&set2_node,¬hing))
		{
			cut_set.DeleteList(set2_node);
		}

	}

	//vc++6.0不支持,会提示i重复定义
	//遍历set1集合
	for (int i = 1; i <=set1.LengthList(); i++)
	{
		//same_set
		set1_node.data=set1.GetList(i)->data;

		if (!set2.FindList(&set1_node,¬hing))
		{
			same_set.DeleteList(set1_node);
		}
	}

	cout<<endl<<"并集:";
	add_set.TraverseList();
	cout<<endl<<"交集:";
	same_set.TraverseList();
	cout<<endl<<"差集:";
	cut_set.TraverseList();
	cout<<endl;

	char ch=getchar();
	return 0;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值