链式描述线性表/链表操作

/********************************************************
*************** 实验四 链式描述线性表/链表操作**************
****************插入操作:1 插入数*************************
****************删除操作:2 删除数*************************
****************查找操作:3 查找数*************************
****************输出操作:4*******************************
****************逆序输出操作:5***************************
****************合并链表操作:6***************************
****************链表一元素数 [链表一所有元素]**************
****************链表二元素数 [链表二所有元素]**************
************************created by fsy*********************
*/

#include<iostream>
#include<numeric>  //accumulate函数
#include<algorithm>
#include <stack>
using namespace std;

int h[1000021];
//结构体功能:表示链表的节点
template <class T>
struct chainNode
{
	// data members
	T element;
	chainNode<T>* next;

	// methods
	chainNode() {}
	chainNode(const T& element)
	{
		this->element = element;
	}
	chainNode(const T& element, chainNode<T>* next)
	{
		this->element = element;
		this->next = next;
	}
};

//类功能:链表的定义
template<class T>
class chain
{
protected:
	chainNode<T>* firstNode;//指向列表的头节点的指针
	//当链表为空时,firstNode指向NULL
	int listSize;  //线性表的元素个数
public:
	chain(int initialCapacity = 10);
	chain(const chain<T>&);
	~chain();

	//抽象数据类型ADT的方法
	bool checkIndex(const int theIndex);
	bool empty() const { return listSize == 0; }
	int size() const { return listSize; }
	T& get(int theIndex) const;
	int indexOf(const T& theElement) const;
	void erase(int theIndex);
	void insert(int theIndex, const T& theElement);
	void print();
	int size();


	//链表迭代器
      class iterator
      {
         public:
            //C++语言的向前迭代器所需要的typedefs
            typedef forward_iterator_tag iterator_category;
            typedef T value_type;
            typedef ptrdiff_t difference_type;
            typedef T* pointer;
            typedef T& reference;

            //构造函数
            iterator(chainNode<T>* theNode = NULL)
               {node = theNode;}

            //解引用操作符
            T& operator*() const {return node->element;}
            T* operator->() const {return &node->element;}

            //迭代器加法操作
            iterator& operator++()   // preincrement
                      {node = node->next; return *this;}
            iterator operator++(int) // postincrement
            	      {iterator old = *this;
            	       node = node->next;
            	       return old;
            	      }

            //相等检验
            bool operator!=(const iterator right) const
                  {return node != right.node;}
            bool operator==(const iterator right) const
                  {return node == right.node;}
         protected:
            chainNode<T>* node;
      };  //链表结尾
	class iterator;
      iterator begin() {return iterator(firstNode);}
      iterator end() {return iterator(NULL);}
};

//函数功能:单项链表的构造函数
template<class T>
chain<T>::chain(int initialCapacity)
{
	if (initialCapacity < 1)
	{
		cout << "Initial capacity = " << initialCapacity << " Must be > 0";
		cout << "请重新输入一个初始大小" << endl;
		cin >> initialCapacity;
		chain(initialCapacity);
	}
	firstNode = NULL;
	listSize = 0;
}

//函数功能:单向链表的复制构造函数
template<class T>
chain<T>::chain(const chain<T>& theList)
{
	listSize = theList.listSize;

	//如果链表本身是空的
	if (listSize == 0)
	{
		firstNode = NULL;
		return;
	}

	//链表theList不是空的

	//复制链表的首节点
	chainNode<T>* sourceNode = theList.firstNode;
	//复制链表的首元素
	firstNode = new chainNode<T>(sourceNode->element);
	sourceNode = sourceNode->next;
	//当前链表*this的最后一个节点
	chainNode<T>* targetNode = firstNode;

	//复制链表的剩余的元素
	//如果链表没有到末尾(末尾为null)
	//就复制后继续往前指向
	while (sourceNode != NULL)
	{
		targetNode->next = new chainNode<T>(sourceNode->element);
		targetNode = targetNode->next;
		sourceNode = sourceNode->next;
	}
	targetNode->next = NULL;//链表的结尾
}

//函数功能:链表的析构函数
//删除链表的所有节点
template<class T>
chain<T>::~chain()
{
	chainNode<T> *nextNode;
	//如果链表当前节点指的不是NULL(结尾是NULL)
	//就删除掉这个节点后继续往前指
	while (firstNode != NULL)
	{
		//指向节点的指针
		//用变量nextNode保存第二个节点的指针
		nextNode = firstNode->next;
		delete firstNode;
		firstNode = nextNode;
	}
}

//检查该节点是否有元素
//易证这里的选择应该是>而不是>=
template<class T>
bool chain<T>::checkIndex(const int theIndex)
{// Verify that theIndex is between 0 and listSize - 1.
	if (theIndex < 0 || theIndex > listSize)
	{
		cout << "index = " << theIndex << " size = " << listSize<<endl;
		return false;
	}
	else
		return true;
}

//功能:返回索引为theIndex处的元素
//如果不存在则返回一场
template<class T>
T& chain<T>::get(int theIndex) const
{
	if (checkIndex(theIndex))
	{
		chainNode<T>* currentNode = firstNode;
		for (int i = 0; i < theIndex; i++)
		{
			currentNode = currentNode->next;
		}
		return currentNode->element;
	}
}

//功能:返回元素theElement第一次出现时的索引
//若该元素不存在,则返回-1
template<class T>
int chain<T>::indexOf(const T& theElement) const
{
	//查找元素theElement
	chainNode<T>* currentNode = firstNode;
	int index = 0;  //现在所在的索引

	//如果指针没有走到结尾且指针所指的元素不是要找的元素
	//指向结尾,或指向要找元素时退出
	while (currentNode != NULL &&
		currentNode->element != theElement)
	{
		//指针指向下一个元素
		currentNode = currentNode->next;
		index++;//该指针的索引加一
	}

	//确定元素theElement是否被找到
	if (currentNode == NULL)
		return -1;
	else
		return index;
}


//删除其索引为theIndex的元素
template<class T>
void chain<T>::erase(int theIndex)
{
	if (checkIndex(theIndex))
	{
		chainNode<T>* deleteNode;
		if (theIndex == 0)
		{//删除指针指向首元素
		 //第二个元素取代第一个元素成为首元素
			deleteNode = firstNode;
			firstNode = firstNode->next;
		}
		else
		{//使用指针p指向要删除节点的前驱节点
			chainNode<T>* p = firstNode;
			for (int i = 0; i < theIndex - 1; i++)
			{
				p = p->next;
			}
			//删除指针指向要删除元素
			deleteNode = p->next;
			//前驱节点的下一个元素变为要删除元素的后一个元素
			p->next = p->next->next;
		}
		listSize--; //链表元素数减一
		delete deleteNode;
	}
}

//在索引为theIndex的位置上插入元素theElement
template<class T>
void chain<T>::insert(int theIndex, const T& theElement)
{
	if (theIndex == 0)
	{
		//如果theIndex为0则在链表头插入
		//这是结构体中默认的插在表头的元素函数
		firstNode = new chainNode<T>(theElement, firstNode);
		listSize++;//链表元素数量++
	}
	else
	{
		if (checkIndex(theIndex))
		{
           //寻找新元素的前驱
			chainNode<T>* p = firstNode;
			for (int i = 0; i < theIndex - 1; i++)
			{//p指向插入位置的前一个元素
				p = p->next;
			}
			//在插入位置使用链表结构体里的自带函数
			p->next = new chainNode<T>(theElement, p->next);
			listSize++;
		}
	}
}


//函数功能:打印链表
template<class T>
void chain<T>::print()
{
	//把链表放入输出流
	//这是一个for循环
	for (chainNode<T>* currentNode = firstNode;
		currentNode != NULL;
		currentNode = currentNode->next)
	{
		cout << currentNode->element << "  ";
	}
}



template<class T>
int chain<T>::size()
{
	return listSize;
}


int main()
{

	int n;//有多少次操作
	cin >> n;
	int operation;
	int list1number; //合并链表时链表一的元素数
	int list2number; //合并链表时链表二的元素数
	int indexNumber;//数的序号
	int number;//插入,删除,查找的各个数
	int ans; //查找结果
	chain<int> a;
	stack<int> s1;

	while (n--)
	{
		cin >> operation;
		//插入操作:1 插入数
		if (operation == 1)
		{
			cin >> number;
			a.insert((int)0,number);
		}
		//删除操作:2 删除数
		if (operation == 2)
		{
			cin >> number;
			indexNumber = a.indexOf(number);
			a.erase(indexNumber);
		}
		//查找操作:3 查找数
		if (operation == 3)
		{
			cin >> number;
			ans = a.indexOf(number);
			cout << ans << endl;
		}
		//输出操作:4
		if (operation == 4)
		{
			for (chain<int>::iterator i = a.begin();
				i != a.end(); i++)
			{
				cout << *i<<" ";
			}
			cout << endl;
		}
		//逆序输出操作:5
		if (operation == 5)
		{
			for (chain<int>::iterator i = a.begin();
				i != a.end(); i++)
			{
				s1.push(*i);
			}
			while(s1.empty()==false)
			{
				number = s1.top();
				cout << number << " ";
				s1.pop();
			}
			cout << endl;
		}
		//合并链表操作:6
		//链表一元素数 [链表一所有元素]
		//链表二元素数[链表二所有元素]
		if (operation == 6)
		{
			cin >> list1number;
			chain<int> a1;
			for (int i = 0;i < list1number;i++)
			{
				cin >> h[i];
			}
			cin >> list2number;
			chain<int> a2;
			for (int i = list1number;i < list1number + list2number;i++)
			{
				cin >> h[i];
			}
			sort(h, h + list1number + list2number);
			for (int i = 0;i < list1number + list2number; i++)
			{
				cout<<h[i]<<" ";
			}
			cout << endl;
		}
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值