链表 讲义实现

本文深入探讨了链表的数据结构,包括初始化、获取指定位置元素、插入、删除等基本操作,以及正序和逆序建表的方法。此外,还介绍了如何合并两个有序链表的高级操作,并提供了完整的源代码实现。
摘要由CSDN通过智能技术生成

在这里插入图片描述

在这里插入图片描述

链表的结构表示

template <class T>
struct Node
{
	T data;
	Node<T> *next;
	//Node(Node<T> *ptr=NULL):next(ptr){}
};

template <class T>
class LinkList
{
public:
	LinkList();
	~LinkList();
	Status PositiveCreateList(int n);	//正序建表
	Status ReverseCreateList(int n);	//逆序建表
	void Display();
	int GetLength() const;
	Status ListInsert(int i, T e);
	Status ListDelete(int i, T &e);
	Status GetElem_byID(int i, T &e);	//已知下标返回值
	Status GetElem_byKey(T key, int &i);	//已知值返回下标
	void MergeList(LinkList La, LinkList Lb);
	Status Reverse();
	Status ReverseHere();

private:
	Node<T> *head;

};

初始化操作

template <class T>
LinkList<T>::LinkList()
{
	head = new Node<T>;
	head->next = NULL;
}

获取单链表中指定位置的元素

template <class T>
Status LinkList<T>::GetElem_byID(int i, T &e)
{
	Node<T> *p;
	p = head->next;	//p指向首元节点
	int j = 1;		//初始化,p指向第一个节点,j为计数器
	while(p!=NULL && j<i)	//顺指针向后查找,直到p指向第i个元素或者为空
	{
		p = p->next;
		j++;
	}
	if(p==NULL || j>i)
	{
		return ERROR;	//第i个元素不存在
	}
	e = p->data;
	return OK;
}

在这里插入图片描述

插入操作

template <class T>
Status LinkList<T>::ListInsert(int i, T e)
{
	Node<T> *p, *s;
	p = head;
	int j = 0;
	while(p!=NULL && j<i-1)	//寻找第i-1个节点
	{
		p = p->next;
		++j;
	}
	if(p==NULL || j>i-1)
	{
		return ERROR;
	}
	s = new Node<T>;	//生成新节点
	s->data = e;
	s->next = p->next;
	p->next = s;
	return OK;
}

在这里插入图片描述

删除操作

template <class T>
Status LinkList<T>::ListDelete(int i, T &e)
{
	Node<T> *p, *q;
	p = head;
	int j = 0;
	while(p->next && j<i-1)	//寻找第i个节点,并令p指向其前趋
	{
		p = p->next;
		++j;
	}
	if(!(p->next) || j>i-1)
	{
		return ERROR;
	}
	q = p-next;
	p->next = q->next;
	e = q->data;
	delete q;
	return OK;
}

正序建表
在这里插入图片描述

template <class T>
Status LinkList<T>::PositiveCreateList(int n)
{
    Node<T> *p, *last;
    last = head;	//保留last指针
    for(int i=1; i<=n; i++)
	{
		p = new Node<T>;
		if(p == NULL)
		{
			return ERROR;
		}
		p ->data = rand();
		last->next = p;		//插到表尾
		last = p;	//last后移
	}
	last->next = NULL;
	return OK;
}

逆序建表
在这里插入图片描述

//头插法建立链表,逆位序输入n个元素的值
//建立带头结点的单链线性表
template <class T>
Status LinkList<T>::ReverseCreateList(int n)
{
	Node<T> *p;
	for(int i=n; i>0; i--)
	{
		p = new Node<T>;	//生成新节点
		if(!p)
		{
			return ERROR;
		}
		p->data = rand();		//生成一个随机数字
		p->next = head->next;
		head->next = p;		//插入到表头
	}
	return OK;
}

两个有序表的合并操作

template <class T>
void LinkList<T>::MergeList(LinkList La, LinkList Lb)
{
	Node<T> *pa, *pb, *pc, *p;
	pa = La.head->next;
	pb = Lb.head->next;
	pc = head;
	while(pa && pb)
	{
		if(pa->data >= pb->data)
		{
			p = new Node<T>;
			p->data = pa->data;
			pc->next = p;
			pc = pc->next;
			pa = pa->next;
		}
		else
		{
			p = new Node<T>;
			p->data = pb->data;
			pc->next = p;
			pc = pc->next;
			pb = pb->next;
		}
	}
	while(pa)
	{
		p = new Node<T>;
		p->data = pa->data;
		pc->next = p;
		pc = pc->next;
		pa = pa->next;
	}
	while(pb)
	{
		p = new Node<T>;
		p->data = pb->data;
		pc->next = p;
		pc = pc->next;
		pb = pb->next;
	}
}

完整源码

#include <iostream>
#include <cstdlib>
using namespace std;

const int OK = 1;
const int ERROR = 0;

typedef int Status;

template <class T>
struct Node
{
	T data;
	Node<T> *next;
	//Node(Node<T> *ptr=NULL):next(ptr){}
};

template <class T>
class LinkList
{
public:
	LinkList();
	~LinkList();
	Status PositiveCreateList(int n);	//正序建表
	Status ReverseCreateList(int n);	//逆序建表
	void Display();
	int GetLength() const;
	Status ListInsert(int i, T e);
	Status ListDelete(int i, T &e);
	Status GetElem_byID(int i, T &e);	//已知下标返回值
	Status GetElem_byKey(T key, int &i);	//已知值返回下标
	void MergeList(LinkList La, LinkList Lb);
	Status Reverse();
	Status ReverseHere();

private:
	Node<T> *head;

};

template <class T>
LinkList<T>::LinkList()
{
	head = new Node<T>;
	head->next = NULL;
}

template <class T>
LinkList<T>::~LinkList()
{
	Node<T> *p = head;
	while(p!=NULL)
	{
		head = head->next;
		delete p;
		p = head;
	}
}

template <class T>
Status LinkList<T>::GetElem_byID(int i, T &e)
{
	Node<T> *p;
	p = head->next;	//p指向首元节点
	int j = 1;		//初始化,p指向第一个节点,j为计数器
	while(p!=NULL && j<i)	//顺指针向后查找,直到p指向第i个元素或者为空
	{
		p = p->next;
		j++;
	}
	if(p==NULL || j>i)
	{
		return ERROR;	//第i个元素不存在
	}
	e = p->data;
	return OK;
}

template <class T>
Status LinkList<T>::GetElem_byKey(T key, int &i)
{
	i = 0;
	Node<T> *p = head->next;
	if(p == NULL)
	{
		return ERROR;
	}
	while(p != NULL)
	{
		++i;
		if(p->data == key)
		{
			return OK;
		}
		p = p->next;
	}
	return ERROR;
}


template <class T>
Status LinkList<T>::ListInsert(int i, T e)
{
	Node<T> *p, *s;
	p = head;
	int j = 0;
	while(p!=NULL && j<i-1)	//寻找第i-1个节点
	{
		p = p->next;
		++j;
	}
	if(p==NULL || j>i-1)
	{
		return ERROR;
	}
	s = new Node<T>;	//生成新节点
	s->data = e;
	s->next = p->next;
	p->next = s;
	return OK;
}


template <class T>
Status LinkList<T>::ListDelete(int i, T &e)
{
	Node<T> *p, *q;
	p = head;
	int j = 0;
	while(p->next && j<i-1)	//寻找第i个节点,并令p指向其前趋
	{
		p = p->next;
		++j;
	}
	if(!(p->next) || j>i-1)
	{
		return ERROR;
	}
	q = p->next;
	p->next = q->next;
	e = q->data;
	delete q;
	return OK;
}

template <class T>
void LinkList<T>::Display()
{
	Node<T> *p = head->next;
	while(p!=NULL)
	{
		cout << p->data << " ";
		p = p->next;
	}
	cout << endl;
}

template <class T>
int LinkList<T>::GetLength() const
{
	Node<T> *p = head->next;
	int cnt = 0;
	while(p != NULL)
	{
		cnt++;
		p = p->next;
	}
	return cnt;
}

template <class T>
Status LinkList<T>::PositiveCreateList(int n)
{
    Node<T> *p, *last;
    last = head;	//保留last指针
    for(int i=1; i<=n; i++)
	{
		p = new Node<T>;
		if(p == NULL)
		{
			return ERROR;
		}
		p ->data = rand();
		last->next = p;		//插到表尾
		last = p;	//last后移
	}
	last->next = NULL;
	return OK;
}

//头插法建立链表,逆位序输入n个元素的值
//建立带头结点的单链线性表
template <class T>
Status LinkList<T>::ReverseCreateList(int n)
{
	Node<T> *p;
	for(int i=n; i>0; i--)
	{
		p = new Node<T>;	//生成新节点
		if(!p)
		{
			return ERROR;
		}
		p->data = rand();		//生成一个随机数字
		p->next = head->next;
		head->next = p;		//插入到表头
	}
	return OK;
}

template <class T>
void LinkList<T>::MergeList(LinkList La, LinkList Lb)
{
	Node<T> *pa, *pb, *pc, *p;
	pa = La.head->next;
	pb = Lb.head->next;
	pc = head;
	while(pa && pb)
	{
		if(pa->data >= pb->data)
		{
			p = new Node<T>;
			p->data = pa->data;
			pc->next = p;
			pc = pc->next;
			pa = pa->next;
		}
		else
		{
			p = new Node<T>;
			p->data = pb->data;
			pc->next = p;
			pc = pc->next;
			pb = pb->next;
		}
	}
	while(pa)
	{
		p = new Node<T>;
		p->data = pa->data;
		pc->next = p;
		pc = pc->next;
		pa = pa->next;
	}
	while(pb)
	{
		p = new Node<T>;
		p->data = pb->data;
		pc->next = p;
		pc = pc->next;
		pb = pb->next;
	}
	pc->next = NULL;
}

//新开辟空间的反转
template <class T>
Status LinkList<T>::Reverse()
{
	Node<T> *p = head->next;
	Node<T> *q = p;
	if(p == NULL)
		return ERROR;
	bool flag = false;
	while(p != NULL)
	{
		Node<T> *s = new Node<T>;
		s->next = NULL;
		s->data = p->data;
		p = p->next;
		delete q;	//逐个释放节点
		q = p;
		if(flag)
		{
			s->next = head->next;
		}
		else
		{
			flag = true;
		}

		head->next = s;
	}

	return OK;
}

//就地反转
template<class T>
Status LinkList<T>::ReverseHere()
{
	if(head->next == NULL)
	{
		return ERROR;
	}
	if(head->next->next == NULL)
	{
		return OK;
	}
	Node<T> *p = head->next->next;
	head->next->next = NULL;
	Node<T> *q = p->next;
	while(p != NULL)
	{
		p->next = head->next;
		head->next = p;
		p = q;
		if(q != NULL)
		{
			q = q->next;
		}
	}
	return OK;
}

int main()
{
	LinkList<int> list1;
	list1.PositiveCreateList(10);
	cout << "List1 : ";
	list1.Display();
	cout << "List1的长度为:";
	cout << list1.GetLength()<<endl;
	int temp = 0;
	list1.GetElem_byID(4, temp);
	cout << "List1中第4个元素是: " <<temp<<endl;
	int i=0;
	list1.GetElem_byKey(15724, i);
	cout << "List1中值为15724的元素在第"<< i << "个位置"<<endl;

	cout << "在List1中第3个位置插入值23456"<<endl;
	list1.ListInsert(3, 23456);
	list1.Display();
	cout << "删除该元素";
	list1.ListDelete(3, temp);
	list1.Display();



	LinkList<int> list2;
	list2.ReverseCreateList(10);
	cout << "List2 : ";
	list2.Display();

	LinkList<int> list3, list4, list5;
	for(int i=1; i<=10; i++)
	{
		list4.ListInsert(1, 2*i-1);
		list5.ListInsert(1, 2*i);
	}
	cout << "List4, List5如下:"<<endl;
	list4.Display();
	list5.Display();
	list3.MergeList(list4, list5);
	cout << "合并后的list3为:"<<endl;
	list3.Display();

	cout << "反转操作:"<<endl;

	cout << "L2新开辟空间的反转:";
	list2.Reverse();
	list2.Display();

	cout << "List1就地反转:";
	list1.ReverseHere();
	list1.Display();

	return 0;
}

结果如下:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值