妙趣横生的算法学习3(单链表)

1.2链表

链表也是一种线性表,他的逻辑结构也是一维的,但它存储的物理结构与顺序表有很大不同。

链表的定义:

链表是将数据元素存放在不连续的地址空间中的一种线性表。链表分为单链表、双链表和循环链表几类。

单链表:

每一个结点包含两部分数据域和下一个结点的地址(指针域)。一个链表通常有一个表头,存放第一个结点的地址。每个结点后面的一个结点称为此结点的后继,链表有一个表尾,表尾没有后继,所以尾指针的指针域为NULL。

单链表具有如下特征:

1.物理位置不一定连续,逻辑上通过指针实现连续

2.有一个头结点和尾结点,并且只有尾结点没有后继结点,其他结点有且仅有一个后继结点。

3.只要知道了链表的头结点,就可以遍历整个链表

链表结构声明如下:

template <typename DataType>class LinkList
{
	public:
		LinkList()
		{
			head=new ListNode();
		}
		LinkList(LinkNode *node)
		{
			head=node;
		}
		~LinkList()
		{
			delete head;
		}
		bool insertNode(ListNode *q,DataType newData);
		bool removeNode(ListNode *q);
		ListNode *findNode(DataType value);
		bool cleanLink();
		DataType getNodeData(ListNode *p);
	private:
		ListNode *head;
};

链表结点声明如下:

template<typename Datatype> class ListNode
{
	public:
		ListNode()
		{
			next=NULL;
		}
		ListNode(DataType item,ListNode<Datatype> *nextNode=NULL)
		{
			data=item;
			next=nextNode;
		}
		~ListNode()
		{
			next=NULL;
		}
		Datatype getData()
		{
			return data;
		}
		ListNode *getNext()
		{
			return next;
		}
	private:
		friend typename LinkList<DataType>;
		DataType *next;
		DataType *data;
}
此处设置了两个类,一个是表示结点的LinkNode类,另一个是表示链表整体的LinkList类。在这里我们将LinkList类设为LinkNode的友元类,方便链表类对结点类的内部成员变量和成员方法进行访问。


1.2.2链表的基本操作

操作主要有:

1.插入结点操作

2.删除结点操作

3.查找指定值结点操作

4.清空列表操作


1.插入结点

插入结点操作思路大致如下:

1.创建一个待插入的结点p,为其分配内存空间,并将其指针域设置为NULL。

2.找到单链表的第i个结点位置,获取他的地址q,将结点p插入在结点q与其后继结点之间。

其实现代码如下:

template<typename DataType> bool LinkList<DataType>::insertNode(int i,DataType newData)
{
	ListNode<Datatype> *p=head;
	int j;
	for(j=1;j<=i-1;j++)
	{
		p=p->next;
		if(p==NULL)
		{
			break;
		}
	}
	if(p==NULL && j<(i-1))
	{
		std::cout<<"插入位置无效!"<<std::endl;
		return false;
	}
	ListNode<DataType> *node=new ListNode<DataType>(newData);
	node->next=p->next;
	p->next=node;
	return true;
}

那么如何在单链表中添加新结点呢?

template<typename DataType> bool LinkList<DataType>::insertNode(DataType newData)
{
	ListNode<DataType> *p=head;
	ListNode<DataType> *node=new ListNode<DataType>(newData);
	if(node==NULL)
	{
		return false;
	}
	while(p->next !=NULL)
	{
		p=p->next;
	}
	p->next=node;
	return true;
}

2.删除结点

template<typename DataType>bool LinkList<DataType>::removeNode(ListNode<Datatype> *q)
{
	if(q==NULL)
	{
		std::cout<<"待删除结点不存在!"<<std::endl;
		return false;
	}
	LinkNode<DataType> *tempPointer=head;
	while(tempPointer->next !=q)
	{
		tempPointer=tempPointer->next;
	}
	tempPointer->next=q->next;
	delete q;
	return true;
}

3.查找特定值结点

template<typename DataType> ListNode<DataType>* LinkList<DataType>::findNode(DataType value)
{
	ListNode<DataType> *currentPointer=head;
	while(currentPointer!=NULL && currentPointer->data !=value)
	{
		currentPointer=currentPointer->next;
	}
	if(currentPointer==NULL)
	{
		std::cout<<"没有找到该结点!程序异常退出!"<<std::endl;
		exit(1);
	}
	else
	{
		return currentPointer;
	}
}

4.清空链表

template<typename DataType> void LinkList<DataType>::cleanLink()
{
	ListNode<DataType> *current =head;
	while(head->next !=NULL)
	{
		current=head->next;
		head->next=current->next;
		delete current;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值