利用C++实现一个链表结构

利用C++实现链表结构

1.定义链表的数据结构

CList作为一个链表类,它的成员是由CNode组成

CNode有两个属性,tElement用于指向当前的节点,next用于指向下一个节点

/********************************************************
**	CList链表结构实现
**
**
**
***********************************************************/

#ifndef _LIST_
#define _LIST_

#include <Windows.h>

template <class T>  //利用泛型编程笔迷避免链表节点与链表耦合
//链表节点
class CNode
{
public:
	CNode(T* tElement) : tElement(tElement), next(0) { }
	T* Element() const { return tElement; }
	CNode*& Next(){ return next; }
private:
	T* tElement;//用于指示当前节点
	CNode* next;//用于指示下一个节点
};
template <class T>
class CList
{
public:
	CList() : dwCount(0), head(0){ }
	CList(T* tElement) : dwCount(1), head(new CNode<T>(tElement)){ }
	virtual ~CList(){ }
	void Append(CNode<T>*& node, T* tElement);//添加
	void Insert(T* tElement);//插入
	bool Remove(T* tElement);//溢出
	DWORD Count() const { return dwCount; }//节点数量
	CNode<T>*& Head() { return head; }//节点头
	T* GetFirst(){ return head != NULL ? head->Element() : NULL; }
	T* GetLast();
	T* GetNext(T* tElement);
	T* Find(DWORD(*Function)(T* tParameter), DWORD dwValue);
protected:
	CList(const CList& list);
	CList& operator = (const CList& list);
private:
	CNode<T>* head;
	DWORD dwCount;
};

template <class T>
void CList<T>::Append(CNode<T>*& node, T* tElement)
{
	if (node == NULL)
	{
		dwCount++;
		node = new CNode<T>(tElement);

		return;
	}

	Append(node->Next(), tElement);
}

template <class T>
void CList<T>::Insert(T* tElement)
{
	dwCount++;
	if (head == NULL)
	{
		head = new CNode<T>(tElement);
		return;
	}

	CNode<T>* tmp = head;
	head = new CNode<T>(tElement);
	head->Next() = tmp;
}

template <class T>
bool CList<T>::Remove(T* tElement)
{
	if (head == NULL)
	{
		return NULL;
	}

	if (head->Element() == tElement)
	{
		CNode<T>* tmp = head;
		head = head->Next();

		delete tmp;
		dwCount--;

		return true;
	}

	CNode<T>* tmp = head;
	CNode<T>* lst = head->Next();

	while (lst != NULL)
	{
		if (lst->Element() == tElement)
		{
			tmp->Next() = lst->Next();

			delete lst;
			dwCount--;

			return true;
		}

		lst = lst->Next();
		tmp = tmp->Next();
	}

	return false;
}

template <class T>
T* CList<T>::GetLast()
{
	if (head)
	{
		CNode<T>* tmp = head;
		while (tmp->Next())
		{
			tmp = tmp->Next();
		}
		return tmp->Element();
	}

	return NULL;
}

template <class T>
T* CList<T>::GetNext(T* tElement)
{
	if (head == NULL)
	{
		return NULL;
	}

	if (tElement == NULL)
	{
		return GetFirst();
	}

	if (head->Element() == tElement)
	{
		return head->Next() != NULL ? head->Next()->Element() : NULL;
	}

	CNode<T>* lst = head->Next();

	while (lst != NULL)
	{
		if (lst->Element() == tElement)
		{
			return lst->Next() != NULL ? lst->Next()->Element() : NULL;
		}

		lst = lst->Next();
	}

	return NULL;
}

template <class T>
T* CList<T>::Find(DWORD(*Function)(T* tParameter), DWORD dwValue)
{
	try
	{
		T* tElement = NULL;
		while (tElement = GetNext(tElement))
		{
			if (Function(tElement) == dwValue)
			{
				return tElement;
			}
		}
	}
	catch (...) {}

	return NULL;
}

#endif

  

CQueue定义代码如下

#ifndef __QUEUE__
#define __QUEUE__

#include "CList.h"

template<class T>
class CQueue : CList<T>
{
public:
	CQueue() : CList<T>(){ }
	CQueue(T* tElement) : CList<T>(tElement){ }
	virtual ~CQueue(){ }
	virtual void Enqueue(T* tElement)
	{
		Append(Head(), tElement);
	}
	virtual T* Dequeue()
	{
		T* tElement = GetFirst();
		Remove(tElement);
		return tElement;
	}
	virtual T* Peek()
	{
		return GetFirst();
	}
	CList<T>::Count;
protected:
	CQueue(const CQueue<T>& cQueue);
	CQueue<T>& operator = (const CQueue<T>& cQueue);
};

#endif

  

#include <iostream>

using namespace std;

#include "CQueue.h"
#include "CStack.h"

int _main()
{
	CQueue<int>* cQueue = new CQueue<int>();
	CStack<double>* cStack = new CStack<double>();

	for (int i = 0; i < 10; i++)
	{
		cQueue->Enqueue(new int(i));
		cStack->Push(new double(i / 10.0));
	}

	cout << "Queue - integer collection:" << endl;
	for (; cQueue->Count();)
	{
		cout << *cQueue->Dequeue() << " ";
	}

	cout << endl << endl << "Stack - double collection:" << endl;
	for (; cStack->Count();)
	{
		cout << *cStack->Pop() << " ";
	}

	delete cQueue;
	delete cStack;

	cout << endl << endl;
	return system("pause");
}

  

原文地址:https://www.cnblogs.com/yuanshijie/p/12297995.html

时间: 2024-10-29 13:00:53

利用C++实现一个链表结构的相关文章

利用java实现一个简单的链表结构

定义: 所谓链表就是指在某节点存储数据的过程中还要有一个属性用来指向下一个链表节点,这样的数据存储方式叫做链表 链表优缺点: 优点:易于存储和删除 缺点:查询起来较麻烦 下面我们用java来实现如下链表结构: 首先定义节点类: 复制代码package LinkTest;/** 链表节点类 @author admin */public class Node {private int value;//存储数据private Node next;//下一个节点/** 定义构造器 @param vlau

算法总结之 判断一个链表是否是回文结构

给定一个链表的头节点head,判断是否是回文结构 1->2->1 返回true 进阶: 如果链表长度N,时间复杂度O(N) 额外空间O(1) 方法一 利用栈结构(需要额外空间) 从左到右遍历,一次压栈.   这样的到的  从栈顶到栈底的节点值出现顺序会与原链表从左到右的值出现顺序相反. 废话不多说,上代码: package TT; import java.util.Stack; public class Test92 { public class Node{ public int value;

C++算法之 倒序输出一个链表

题目:给定一个头结点,倒叙输出一个链表 解法1:先将链表反转,在遍历输出 解法2:不修改链表自身的结构,动态申请一段空间,申请一个指针数组,数组内存放的指针指向链表的每个值,再遍历数组输出: void PrintListBack(ListNode* head) { int n = GetLength(head); ListNode** p = new ListNode*[n+1]; p[n] = NULL; int i = 0; ListNode* pNode = head; while (i

利用React写一个评论区组件(React初探)

本文是在阅读学习了官方的React Tutorial之后的整理,实例链接. 开始使用React 首先从官方获取React.js的最新版本(v0.12.2),或者下载官方的Starter Kit,并在我们的html中引入它们: <head> <meta charset="UTF-8"> <title>React Test Page</title> <script src="../build/react.js">

Pjlib中的链表结构

Pjlib的链表结构跟常见的链表结构有所区别,如下图所示: ? ? ? ? ? ? 图1:一般链表结构 ? ? ? ? ? 图2:pjlib中的链表结构 可以看到一般的双向链表是链表节点包含数据域,而pjlib中是数据域包含链表节点.一般的链表指针域是链表结构的指针,而pjlib中是数据结构的指针.这种结构的优势我还没有体会到,可能要慢慢体会吧,但对链表头的理解却造成些许困惑.链表头是一个单独的list,而prev和next指向的是含有list的data结构,这种结构总让我觉得怪怪的. Pjli

javascript中的链表结构—双向链表

1.概念 上一个文章里我们已经了解到链表结构,链表的特点是长度不固定,不用担心插入新元素的时候新增位置的问题.插入一个元素的时候,只要找到插入点就可以了,不需要整体移动整个结构. 这里我们了解一下双向链表的结构.尽管从链表中头节点遍历到尾节点很容易,但是反过来,从后向前遍历就没有那么简单.通过给Node对象增加一个属性,该属性存储指向前驱节点的链接,这样就容易多了.此时祥链表中插入一个节点需要更多的工作,我们需要指出该节点正确的前驱和猴急.但是在从链表中删除节点的时候效率更高了,不需要再查找待删

Nginx 链表结构 ngx_list_t

链表结构 ngx_list_t 是 Nginx 封装的链表容器,链表容器内存分配是基于内存池进行的,操作方便,效率高.Nginx 链表容器和普通链表类似,均有链表表头和链表节点,通过节点指针组成链表.其结构定义如下: /* 链表结构 */ typedef struct ngx_list_part_s ngx_list_part_t; /* 链表中的节点结构 */ struct ngx_list_part_s { void *elts; /* 指向该节点数据区的首地址 */ ngx_uint_t

设计鲁棒性的方法:输入一个链表的头结点,逆序遍历打印该链表出来

之前有过整理链表等的概念和基本算法.比较重要的是插入,删除,遍历,建表(尾插法,头插法) 回忆链表尾部插入结点:  1 #include <iostream> 2 using namespace std; 3  4 typedef struct Node{ 5     int data;//数据域 6     Node *next;//指针域 7 } Node, *List; 8  9 //在单链表的末位添加一个结点10 void addNode(List *head, int value)1

指针与链表结构理解

指针与链表结构理解#include<stdio.h>int main(void){ int a=3,*p; p=&a; printf("a=%d,*p=%d\n",a,*p); *p=10; printf("a=%d,*p=%d\n",a,*p); printf("Enter a:"); scanf("%d",&a); printf("a=%d,*p=%d\n",a,*p); r