C++單向鏈表

C++單鏈表
一般很少使用單鏈表。在實際中,使用雙向鏈表居多,並定義一個頭尾指針變量,恆定指向頭尾節點,方便遍歷。

1.只有頭節點的情況

完整代碼如下:

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

#include "stdafx.h"
#include <iostream>
#include <exception>
#include "linearList.h"

using namespace std;

template<class T>
struct chainNode
{
	T element;
	chainNode<T> * next;
	chainNode(const T& element) {
		this->element = element;
		this->next = NULL;
	}
};

template<class T>
class chain : public linearList<T>
{
public:
	chain();
	~chain();

	bool empty() const;
	int size() const;
	T& get(int theIndex) const;
	int indexOf(const T& theElement) const;
	void erase(int theIndex);
	void insert(int theIndex, const T& theElement);
	void insertToTail(const T& theElement);
	void output() const;

	int indexOfNode(chainNode<T>* theNode) const;

	void checkIndex(int theIndex) const;

protected:
	int listSize;
	chainNode<T> * firstNode;
};

template<class T>
chain<T>::chain()
{
	listSize = 0;
	firstNode = NULL;
}

template<class T>
chain<T>::~chain()
{
	chainNode<T> *node, *nextNode;
	node = firstNode;
	while (node) {
		nextNode = node->next;
		delete node;
		node = nextNode;
	}
}

template<class T>
bool chain<T>::empty() const
{
	return listSize > 0;
}

template<class T>
int chain<T>::size() const
{
	return listSize;
}

//給定index,查找節點
template<class T>
T & chain<T>::get(int theIndex) const
{
	checkIndex(theIndex);

	chainNode<T>* node = firstNode;
	for (int i = 0; i < listSize; i++) {
		if (i == theIndex)
			break;
		node = node->next;
	}
	return node->element;
}

//給定節點的值,查找index
template<class T>
int chain<T>::indexOf(const T & theElement) const
{
	chainNode<T>* node = firstNode;
	for (int i = 0; i < listSize; i++) {
		if (node->element == theElement) {
			return i;
		}
		node = node->next;
	}
	return -1;
}

//給定節點,查找index
template<class T>
int chain<T>::indexOfNode(chainNode<T>* theNode) const
{
	chainNode<T>* node = firstNode;
	int i = 0;
	while (node) {
		if (node->next == theNode) {
			return i;
		}
		i++;
	}
	return -1;
}

//刪除一個節點,如果是雙向鏈表就沒有這麼麻煩了
template<class T>
void chain<T>::erase(int theIndex)
{
	chainNode<T>* node = firstNode;
	int i = 0;
	while (node) {
		if (i == (theIndex - 1)) {
			break;
		}
		node = node->next;
		i++;
	}

	if (node) {
		chainNode<T>* tempNode = node->next;
		node->next = tempNode->next;
		delete tempNode;
	}
}

//在指定的index處插入
template<class T>
void chain<T>::insert(int theIndex, const T& theElement) {
	if ((theIndex < 0) || (theIndex > listSize)) {
		throw "index must be in 0 to listSize";
	}

	if (!firstNode) {
		firstNode = new chainNode<T>(theElement);
		listSize++;
		return;
	}

	if (theIndex == 0) {
		chainNode<T>* node = new chainNode<T>(theElement);
		node->next = firstNode;
		firstNode = node;
	}
	else {
		int i = 1;
		chainNode<T>* node = firstNode;
		while (node) {
			if (i == theIndex) {
				break;
			}
			i++;
			node = node->next;
		}

		chainNode<T>* newNode = new chainNode<T>(theElement);
		newNode->next = node->next;
		node->next = newNode;
	}
	listSize++;
}

//在末尾插入
template<class T>
void chain<T>::insertToTail(const T& theElement)
{
	chainNode<T>* node = firstNode;
	while (node->next) {
		node = node->next;
	}
	chainNode<T>* newNode = new chainNode<T>(theElement);
	node->next = newNode;
	listSize++;
}

//從Head開始輸出
template<class T>
void chain<T>::output() const
{
	chainNode<T> *node = firstNode;
	cout << "-------------" << endl;
	while (node) {
		cout << "node->element : " << node->element << endl;
		node = node->next;
	}
}

//檢查index是否越界
template<class T>
void chain<T>::checkIndex(int theIndex) const
{
	if ((theIndex < 0) || (theIndex > listSize)) {
		throw "out of index";
	}
}

int main()
{
	chain<int>* list = new chain<int>();
	list->insert(0, 0);
	list->insert(1, 111);
	list->insert(2, 222);
	list->insert(3, 333);
	list->insert(0, 999);
	list->insertToTail(1000);
	list->output();

	int index = list->indexOf(222);
	cout << "index : " << index << endl;
	cout << "get Index : " << list->get(3) << endl;

	//------
	list->erase(2);
	list->output();

	system("pause");
	return 0;
}

linearList.h

#pragma once
template<class T>
class linearList
{
public:
	virtual ~linearList() {};

	virtual bool empty() const = 0;

	virtual int size() const = 0;

	virtual T& get(int theIndex) const = 0;

	virtual int indexOf(const T& theElement) const = 0;

	virtual void erase(int theIndex) = 0;
	
	virtual void insert(int theIndex, const T& theElement) = 0;

	virtual void output() const = 0;

private:

};

運行結果:
在這裏插入圖片描述

2.添加尾節點指針

添加尾節點指針,方便節點的尾插入

...
protected:
...
	chainNode<T> * lastNode;		//指向鏈表的尾節點
//在末尾插入
template<class T>
void chain<T>::insertToTail(const T& theElement)
{
	/*chainNode<T>* node = firstNode;
	while (node->next) {
		node = node->next;
	}
	chainNode<T>* newNode = new chainNode<T>(theElement);
	node->next = newNode;
	listSize++;*/
	chainNode<T>* newNode = new chainNode<T>(theElement);
	lastNode->next = newNode;
	lastNode = newNode;
}

相應的,在任意位置插入節點的方法也要做改變,如下:

//在指定的index處插入
template<class T>
void chain<T>::insert(int theIndex, const T& theElement) {
	if ((theIndex < 0) || (theIndex > listSize)) {
		throw "index must be in 0 to listSize";
	}

	//頭節點不存在時,直接賦給頭尾節點
	if (!firstNode) {
		firstNode = new chainNode<T>(theElement);
		lastNode = firstNode;
		listSize++;
		return;
	}

	//頭尾指向一個節點,表明鏈表只有一個節點,插入一個節點則將尾節點指向新節點即可
	if (lastNode == firstNode) {
		lastNode = new chainNode<T>(theElement);
		firstNode->next = lastNode;
		listSize++;
		return;
	}

	if (theIndex == 0) {
		chainNode<T>* node = new chainNode<T>(theElement);
		node->next = firstNode;
		firstNode = node;
	}
	else {
		int i = 1;
		chainNode<T>* newNode = new chainNode<T>(theElement);
		chainNode<T>* node = firstNode;
		while (node) {
			if (i == theIndex) {
				break;
			}
			i++;
			node = node->next;
		}
		if (node->next) {
			newNode->next = node->next;
			node->next = newNode;
		}
		else {	//尾節點
			node->next = newNode;
			lastNode = newNode;
		}
	}
	listSize++;
}

其他代碼不變。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章