C++线性链表

链表,不能像数组一样,只要知道下标就能访问,而是,一个个的顺着链子访问。

例:单链表的节点类模版(lb1.h)

template<class T>
class Node				//节点类
{
	Node<T>*next;
	public:
		T data;
		//构造函数,item是数据区,*ptrnext指向Node节点的指针
		Node(const T& item,Node<T>*ptrnext=NULL);
		void InsertAfter(Node<T>*p);//插入节点
		Node<T>*DeleteAfter();//删除节点
		Node<T>*NextNode() const;//下一个节点的地址
};
//类的实现部分
template<class T>
//构造函数,初始化数据和指针成员
Node<T>::Node(const T& item,Node<T>*ptrnext):data(item),next(ptrnext)
{}

//返回私有的指针成员
template<class T>
Node<T>*Node<T>::NextNode()const
{return next;}//返回地址,因为*next是私有的。

//在当前节点之后插入一个节点p
template<class T>
void Node<T>::InsertAfter(Node<T>*p)
{
	p->next=next;//p节点指针域指向当前节点的后继结点
	next=p;	//当前节点的指针域指向p
}

//删除当前节点的后继结点,并返回其地址
template<class T>
Node<T>*Node<T>::DeleteAfter(void)
{
	Node<T>*tempPtr=next;//将欲删除的节点地址储存到tempPtr中
	if(next==NULL)//如果当前节点没有后继结点,则返回NULL
		return NULL;
	next=tempPtr->next;//使当前节点的指针指向tempPtr的后继结点
	return tempPtr;//返回被删除的节点地址
}
例:实现链表操作函数(lb2.h)

#ifndef NODE_LIBRARY
#define NODE_LIBRARY

#include<iostream.h>
#include<stdlib.h>
//头文件实现的是单节点的操作,本函数实现整个链表的操作
#include"单链表的节点类模版.h"

//生成节点
template<class T>
Node<T>*GetNode(const T&item,Node<T>*nextPtr=NULL)
{
	Node<T>*newNode;//*newNode为节点类型
	newNode=new Node<T>(item,nextPtr);//调用节点的构造函数
	if(newNode==NULL)
	{//申请失败回执
		cerr<<"Memory allocation failure!"<<endl;
		exit(1);
	}
	return newNode;//申请成功返回节点
}

enum AppendNewline{noNewline,addNewline};
//输出链表
template<class T>
void PrintList(Node<T>*head,AppendNewline addnl=noNewline)
{
	Node<T>*currPtr=head;//*currPtr初始化地址为head
	while(currPtr!=NULL)
	{
		if(addnl==addNewline)
			cout<<currPtr->data<<endl;
		else
			cout<<currPtr->data<<" ";
		//指针指向下一节点,调用成员函数,因为next是私有的
		currPtr=currPtr->NextNode();
	}
}

//查找节点
template<class T>
int Find(Node<T>*head,T&item,Node<T>*&prevPtr)
{
	Node<T>*currPtr=head;//定义了*currPtr地址为head
	prevPtr=NULL;	//*prevPtr初值为0,作用为查找后删除节点用
	while(currPtr!=NULL)
	{
		if(currPtr->data==item)
			return 1;//找到回执1,我觉得这里用exit(1)好
		//因为这里,如果不break的话prevPtr指针的值就会继续指向查找到节点的指针了,
		//不过未经测试,这个问题放在后面再说
		prevPtr=currPtr;
		currPtr=currPtr->NextNode();
	}
}

//在表头插入节点
template<class T>
void InsertFront(Node<T>*head,T item)
//head指向GetNode,GetNode的next指针指向head的Next指针进行传递。
{head=GetNode(item,head);}

//在表尾添加节点
template<class T>
void InsertRear(Node<T>*&head,const T&item)
{
	Node<T>*newNode,*currPtr=head;
	//如果在链表尾,则插入节点
	if(currPtr==NULL)InsertFront(head,item);
	else
	{
		while(currPtr->NextNode()!=NULL)
			currPtr=currPtr->NextNode();
		newNode=GetNode(item);
		currPtr->InsertAfter(newNode);
	}
}

//删除链表的头节点
template<class T>
void DeleteFront(Node<T>*&head)
{
	Node<T>*p=head;
	if(head!=NULL)
	{
		head=head->NextNode();
		delete p;
	}
}

//删除链表中第一个数据域等于key的节点
template<class T>
void Delete(Node<T>*&head,T key)
{
	Node<T>*currPtr=head,*prevPtr=NULL;
	if(currPtr==NULL)return;
	while(currPtr!=NULL&&currPtr->data!=key)
	{
		prePtr=currPtr;
		currPtr=currPtr->NextNode();
	}
	if(currPtr!=NULL)
	{
		if(prevPtr==NULL)head=head->NextNode();
		else
			prevPtr->DeleteAfter();
		delete currPtr;
	}
}

//在有序链表中插入一个节点
template<class T>
void InsertOrder(Node<T>*&head,T item)
{
	Node<T>*currPtr,*prevPtr,*newNode;
	prevPtr=NULL;
	currPtr=head;
	while(currPtr!=NULL)
	{
		if(item<currPtr->data)break;
		prevPtr=currPtr;
		currPtr=currPtr->nextNode();
	}
	if(prevPtr==NULL)
		InsertFront(head,item);
	else
	{
		newNode=GetNode(item);
		prevPtr->InsertAfter(newNode);
	}
}

//清空链表-产出链表中所有节点
template<class T>
void ClearList(Node<T>*&head)
{
	Node<T>*currPtr,*nextPtr;
	currPtr=head;
	while(currPtr!=NULL)
	{
		nextPtr=currPtr->NextNode();
		delete currPtr;
		currPtr=nextPtr;
	}
	head=NULL;
}

#endif //NODE_LIBRARY
例:从键盘输入10个整数,用这些整数值作为节点数据,生成一个链表,按顺序输出链表中节点数值,

然后从键盘输入一个待查找整数,在链表中查找该整数,若找到则删除该整数所在节点,如果出现

多次,全部删除,然后输出删除节点以后的链表。在程序结束之前清空链表。

#include<iostream.h>
#include"lb1.h"
#include"lb2.h"
void main(void)
{
	Node<int>*head=NULL,*prevPtr,*delPtr;
	int i,key,item;
	for(i=0;i<10;i++)
	{
		cin>>item;
		InsertFront(head,item);
	}
	cout<<"List:";
	PrintList(head,noNewline);
	cout<<endl;
	cout<<"请输入一个要整除的整数:";
	cin>>key;
	prevPtr=head;
	while(Find(head,key,prevPtr)!=NULL)
	{
		if(prevPtr==NULL)
			head=head->NextNode();
		else
			delPtr=prevPtr->DeleteAfter();
		delete delPtr;
	}
	cout<<"List:";
	PrintList(head,noNewline);
	cout<<endl;
	ClearList(head);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值