单项链表

  链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,链表比较方便插入和删除操作。

 

创建头节点

  手动new一个新的Node,将Node的next置为NULL即可。

  head = new Node(0);head->next = NULL;

C++ 单向链表-【基本操作分析与实现]_链表

从头插入一个新的节点

   手动new出一个新的节点p,使p的next的指向head->next所指向的地址,然后将head->next从新指向p即可。

   Node * p = new Node(int);  p->next = head->next;   head->next = p;

C++ 单向链表-【基本操作分析与实现]_单向链表_02

删除指定节点

  先遍历到指定节点的前一个节点,然后通过将前一个节点的next指针指向指定节点的下一个节点,达到悬空指定节点的效果,然后删除指定节点即可。代码请参照后面的完整代码。

 

C++ 单向链表-【基本操作分析与实现]_单向链表_03

修改指定节点

  遍历到指定节点的位置,将其data修改为要修改的值即可。修改代码请参考后面的完整代码。

C++ 单向链表-【基本操作分析与实现]_链表_04

 

链表反转

  定义三个临时节点指向头结点之后的第1个节点p,第2个节点q和第3个节点m。将p->next置为空,然后将q->next = p,然后将p向后移动一个节点,即p = q,最后将q向后移动一个节点,即q = m,最后把m向后移动一个节点,即m = m->next;依此类推直到m等于NULL,然后将q->next = p,最后将head->next指向q(即目前第一个节点疑,也就是原本最后的一个节点)。

  通过三个节点达到从头开始逐个逆序的目的。反转代码请参考后面的完整代码。

C++ 单向链表-【基本操作分析与实现]_头结点_05

// SingleLinkedListNode.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"


//
//  SingleLinedListNode.cpp
//  单项链表
//  Created by huyanfeng 2019.03.19
//

#include <iostream>
using namespace std;

class SingleLinedListNode 
{
public:
	SingleLinedListNode() { CreateSingleLinedListNode(); }
	~SingleLinedListNode() { Clear(); }

private:
	//节点结构
	struct NodeInfo
	{
		int nData;
		NodeInfo * pNext;
		NodeInfo(const int& nData) :nData(nData), pNext(NULL) {}
	};

	//清理链表函数
	void Clear()
	{
		//从头节点开始循环删除
		while (m_pHead)
		{
			NodeInfo * pNext = m_pHead->pNext;
			delete m_pHead;
			m_pHead = pNext;
		}
	}

	//查找数据d的上一个节点位置的函数
	//为了方便后面删除操作
	NodeInfo* find(const int& nData)
	{
		NodeInfo * pNode = m_pHead;
		for (; pNode != NULL; pNode = pNode->pNext)
		{
			if (pNode->pNext->nData == nData)
				break;
		}
		return pNode;
	}

public:
	//创建头结点
	void CreateSingleLinedListNode();
	//插入函数
	void InsertNode(const int& nData);
	//在指定位置插入
	void InsertPos(const int& nData1, const int& nData2);
	//删除指定数据的节点
	void RemoveNode(const int& nData);
	//修改指定数据
	void UpdateNode(const int& nData1, const int& nData2);
	//反转链表函数
	void ReverseNode();
	//打印
	void Print();

private:
	NodeInfo * m_pHead;//头节点
};

//创建头结点
void SingleLinedListNode::CreateSingleLinedListNode()
{
	m_pHead = new NodeInfo(0);
}
//从头插入一个节点
void SingleLinedListNode::InsertNode(const int& nData)
{
	NodeInfo *pNewNode = new NodeInfo(nData);
	pNewNode->pNext = m_pHead->pNext;
	m_pHead->pNext = pNewNode;
}
//打印函数
void SingleLinedListNode::Print()
{
	for (NodeInfo * pNode = m_pHead->pNext; pNode; pNode = pNode->pNext) {
		cout << pNode->nData << endl;
	}
}
//在nNode1位置之后插入nNode2
void SingleLinedListNode::InsertPos(const int& nData1, const int& nData2)
{
	NodeInfo * pNode = find(nData1);
	NodeInfo * qNode = new NodeInfo(nData2);
	qNode->pNext = pNode->pNext;
	pNode->pNext = qNode;
}

//删除
void SingleLinedListNode::RemoveNode(const int& nData)
{
	NodeInfo * pNode = find(nData);
	//因为p是上一个节点的位置,用q来保存
	//要删除的节点的地址
	NodeInfo *qNode = pNode->pNext;
	//通过将上一个节点的next指针指向要删除节点的next指
	//针志向的节点实现断开要删除节点的目的
	pNode->pNext = pNode->pNext->pNext;
	//删除要删除的节点q
	delete qNode;
}

//修改指定数据
void SingleLinedListNode::UpdateNode(const int& nData1, const int& nData2)
{
	NodeInfo * pNode = find(nData1);
	pNode->pNext->nData = nData2;
}

//反转链表
void SingleLinedListNode::ReverseNode()
{
	NodeInfo * pNode = m_pHead->pNext;//头结点之后的第1个节点
	NodeInfo * qNode = m_pHead->pNext->pNext;//头结点之后的第2节点
	NodeInfo * mNode = m_pHead->pNext->pNext->pNext;//头结点之后的第3个节点
	pNode->pNext = NULL;//将头接点之后的第1个节点的next指针置为空
				   //根据m是否为空来判断 以此逆序每一个节点
	while (mNode) 
	{
		qNode->pNext = pNode;
		pNode = qNode;
		qNode = mNode;
		mNode = mNode->pNext;
	}
	//将最后一个节点逆序
	qNode->pNext = pNode;
	//将头从新指向新的的第1个节点(之前的最后一个节点)
	m_pHead->pNext = qNode;
}

int main(int argc, const char * argv[])
{

	// insert code here...
	SingleLinedListNode list;
	list.InsertNode(1);
	list.InsertNode(2);
	list.InsertNode(3);
	list.InsertPos(2, 5);
	list.Print();
	cout << "---------------------" << endl;
	list.RemoveNode(1);
	list.Print();
	cout << "---------------------" << endl;
	list.ReverseNode();
	list.Print();
	cout << "---------------------" << endl;
	list.UpdateNode(5, 4);
	list.Print();
	return 0;
}

结果:

C++ 单向链表-【基本操作分析与实现]_头结点_06