基本数据结构:单链表

链接方式存储的线性表简称为链表(Linked List)。
     链表的具体存储表示为:
  ① 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的)
  ② 链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点的地址(或位置)信息(称为指针(pointer)或链(link))
注意:
  
链式存储是最常用的存储方式之一,它不仅可用来表示线性表,而且可用来表示各种非线性的数据结构。

2、链表的结点结构
  ┌──┬──┐
  │data│next│
  └──┴──┘ 
       data域--存放结点值的数据域

       next域--存放结点的直接后继的地址(位置)的指针域(链域)

3、头指针head和终端结点指针域的表示
     单链表中每个结点的存储地址是存放在其前趋结点next域中,而开始结点无前趋,故应设头指针head指向开始结点,头指针head是个特殊的指针,他就是链表的带头大哥,找到他就可以访问链表中的数据。

      终端结点无后继,故终端结点的指针域为空,即NULL。

4、好了,废话少说,上代码

关于链表定义的代码,LinkedList.h

#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include <iostream>
#include <cstdlib>

using std::cin;
using std::cout;
using std::endl;
using std::istream;
using std::ostream;
using std::cerr;

template <class T>
struct LinkNode
{
	T data;//值域
	LinkNode<T> *link;//指针域

	LinkNode(LinkNode<T> *ptr = nullptr)
	{
		link = ptr;
	}

	LinkNode(const T& item,LinkNode<T> *ptr = nullptr)
	{
		data = item;
		link = ptr;
	}
};

template <class T>
class List
{
public:
	List()//构造函数
	{
		first = new LinkNode<T>;
		length = 0;
	}

	~List()//析构函数
	{
		clear();
		delete first;
	}

	int Length()const;//返回链表长度
	LinkNode<T> *getHead()const{
		return first;
	}
	LinkNode<T> *Search(const T &x);//查找x是否存在链表中
	void clear();//清空链表,仅余头结点
	LinkNode<T> *locate(int i) const;//返回第i个元素,元素下标从1开始
	bool insert(int i,T& t);//在第i个位置插入元素
	bool remove(int i);//移除第i个位置插入元素
	void inverse();//链表翻转

	bool isEmpty()const{
		return (first->link == nullptr)?true:false;
	}

	friend istream& operator >> (istream &in,List<T> &list)
	{
		list.clear();//首先list清空
		LinkNode<T> *first,*last;
		first = list.first;
		last = first;

		while(!in.eof())
		{
			T val;
			in >> val;
			LinkNode<T> *node = new LinkNode<T>(val);
			last->link = node;
			list.length++;
			last = node;
			
		}

		last->link = nullptr;//尾结点指向空
		return in;
	}

	friend ostream& operator << (ostream& out,const List<T> &list)
	{
		LinkNode<T> *p = list.first->link;
		int i = 1;
		while(p != nullptr)
		{
			cout <<"#" << i <<":" << p->data << endl;
			p = p->link;
			++i;
		}
		return out;
	}

protected:
	LinkNode<T> *first;//记录链表头指针
	int length;//记录链表长度
};

template <class T>
void List<T>::clear()
{
	LinkNode<T> *p = first->link;
	LinkNode<T> *q;
	while(p != nullptr)
	{
		q = p;
		p = p->link;//p向后移
		first->link = p;//重新与头结点建立联系
		delete q;//删除结点
		length--;	
	}
}

template <class T>
LinkNode<T> * List<T>::Search(const T &x)
{
	LinkNode<T> *p = this->first->link;
	while(p != nullptr)
	{
		if(p->data == x)
		{
			return p;
		}
		p = p->link;
	}

	return p;
}

template <class T>
LinkNode<T> * List<T>::locate(int i) const
{
	if(i == 0)
	{
		return first;
	}

	if(i < 0 || i > length)
	{
		return nullptr;
	}

	LinkNode<T> *p = first->link;
	for(int j = 1; j < i; j++)
	{
		p = p->link;
	}

	return p;
}

template <class T>
bool List<T>::insert(int i,T& t)
{
	LinkNode<T> *current = locate(i-1);
	if(current == nullptr)
	{
		return false;
	}

	LinkNode<T> *node = new LinkNode<T>(t);
	if(node == nullptr)
	{
		cerr << "memory malloc failed!" << endl;
		exit(1);
	}

	node->link = current->link;
	current->link = node;
	++length;

	return true;
}

template <class T>
bool List<T>::remove(int i)
{
	LinkNode<T> *current = locate(i-1);
	if(current == nullptr)
	{
		return false;
	}

	LinkNode<T> *p = current->link;
	current->link = p->link;
	delete p;
	length--;

	return true;
}


template <class T>
void List<T>::inverse()
{
	LinkNode<T>  *p, *pr,*temp;
	temp = NULL;
	p = first->link;
	while (p != nullptr){

		pr = p;
		first->link = pr;

		p = p->link;
		pr->link = temp;//pr为当前节点,pr的link指向上次记住的节点

		temp = pr;//记住节点,下次循环要用

	}

}

#endif

测试代码,main.cpp

#include "LinkedList.h"
#include <fstream>
using std::ifstream;
using std::ios;

int main()
{
	List<int> list;
	
	//list.init();
	ifstream in = ifstream("list.txt",ios::in);
	in >> list;
	cout << "The initial list in the file is:\n" << list << endl;

	list.inverse();
	cout << "The inverse list in the file is:\n" << list << endl;
/*
	cout << "input the number you want search:";
	int number;
	cin >> number;
	LinkNode<int> *p = list.Search(number);
	if(p == nullptr)
	{
		cout << number << " not exsited" << endl;
	}
	else
	{
		cout  << number << " exsited" << endl;
	}
	
	list.clear();
	cout << "The cleaded list in the file is:\n" << list << endl;*/


	/*cout << "input the index you want locate:";
	int index;
	cin >> index;
	LinkNode<int> *p = list.locate(index);
	if(p == nullptr)
	{
		cout << "element at " << index << " not exsited" << endl;
	}
	else
	{
		cout  << "element at " << index << " is " << p->data <<endl;
	}*/

	/*cout << "input the index、value you want insert ,split by space ";
	int index;
	int value;
	cin >> index >> value;

	if(list.insert(index,value))
	{
		cout << list << endl;
	}*/

	/*cout << "input the index you want delete  ";
	int index;
	cin >> index ;

	if(list.remove(index))
	{
		cout << list << endl;
	}*/

	in.close();
	system("pause");
	return 0;
}

/*
int main()
{
	ifstream in = ifstream("list.txt",ios::in);
	int num;
	if(!in)
	{
		cout << "文件打不开" << endl;
	}
	else
	{
		while(in >> num)
		{
			cout << num;
		}
	}
	
	in.close();
	system("pause");
	return 0;
}*/

测试输入数据文件 list.txt

1 2 3 4 5 6 7 8


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值