【C++】通用单链表
在C++的学习中,採用模板类,而採用虚函数实现多态性。达到通用的目的。结点类数据域被改造为指针,而把数据放在一个抽象类中。由指针与之建立联系。
採用虚函数实现多态性,达到通用的目的。堆内存的分配与释放。关键不是创建,而是释放!
要特别细致揣摩堆内存的分配与释放,删除一个结点时系统自己主动调用结点类析构函数释放结点占用的动态内存。而结点释放时系统自己主动调用数据域类析构函数释放数据类占用的动态内存,本例中数据类释放时系统自己主动调用虚析构函数来实现释放字符串数据的动态内存。一环套一环。一步都不能错。这是使用动态内存分配的关键。即关键不是创建,而是释放!
执行时的多态性须要维护一个动态指针表才干正确指向各相关类中的同名虚函数。所以多态与模板比較,模板的效率更高,标准模板库中用容器来泛型化数据结构中的很多算法。
对数据结构的使用当然借助模板库。
多态不适用于性能要求非常高的实时应用程序。但继承与多态可用与其他很多其他方面,每一种技术都有能够充分发挥自己能力的地方。
源码例如以下:有什么不足的地方希望大家能够指出。谢谢大家。
#include<iostream>
using namespace std; class Object
{
public:
Object()
{}
virtual void Print()=0;
virtual ~Object()
{}
}; class Node
{
private:
Object *info; //数据域用指针指向数据类对象
Node *next;
public:
Node() //生成头结点的构造函数
{
info = NULL;
next = NULL;
}
~Node() //析构函数
{}
void InsertAfter(Node* P)//在当前结点后插入一个结点
{
Node *s = new Node;
s->next = P->next ;
P->next = s;
}
Node* RemoveAfter(Node* P) //删除当前结点的后继结点,返回该结点备用
{
Node *s = P->next ;
P->next = s->next ;
free(s);
return P;
}
void Linkinfo(Object* obj) //把数据对象连接到结点
{
info = obj;
}
Node* GetNext()const //返回next
{
return next;
}
Object* GetInfo()const //返回info
{
return info;
}
friend class List; //以List为友元类。List可直接訪问Node的私有函数
}; class List
{
private:
Node *head,*tail; //链表头指针和尾指针
public:
List() //构造函数,生成头结点(空链表)
{
head = tail = new Node;
}
~List() //析构函数
{
MakeEmpty();
delete head;
}
void MakeEmpty() //清空链表。仅仅余表头结点
{
head->next = NULL;
}
Node* Find(Object * obj) //搜索数据域与定值同样的结点。返回该结点的地址
{
Node *s = head->next;
while(s->GetInfo() != obj)
{
s = s->next;
}
if(s == NULL)
{
return NULL;
}
return s;
}
int Length() //计算单链表长度
{
int count = 0;
Node *s = head->next;
while(s != NULL)
{
s = s->next ;
count++;
}
return count;
}
void PrintList() //打印链表的数据域
{
Node *p = head->next;
while(p != NULL)
{
p->GetInfo()->Print();
p = p->next ;
}
cout<<endl;
}
void InsertFront(Node* p) //可用来向前生成链表
{
p->next = head->next;
head->next = p;
}
void InsertRear(Node* p) //可用来向后生成链表
{
tail->next = p;
tail = p;
}
void InsertOrder(Node* p) //按升序生成链表
{
Node * s = head;
while(s->next->GetInfo() <= p->GetInfo())
{
s = s->next ;
}
p->next = s->next ;
s->next = p;
}
Node* CreatNode() //创建一个结点(孤立结点)
{
Node *s = new Node;
return s;
}
void DeleteNode(Node* p) //删除指定结点
{
Node *s = head;
while(s->next != p)
{
s = s->next ;
}
s->next = p->next ;
free(p);
}
Node* GetHead()const
{
return head;
}
}; class Int : public Object
{
public:
Int(int x=0):m_x(x)
{}
void Print()
{
cout<<m_x<<" ";
}
private:
int m_x;
}; class String : public Object
{
public:
String(const char *str="")
{
m_data = new char[strlen(str)+1];
strcpy(m_data,str);
}
void Print()
{
cout<<m_data<<" ";
}
private:
char *m_data;
}; void main()
{
List mylist;
Node *pnode = NULL;
Int *pi = NULL;
for(int i=1; i< 6; ++i)
{
pnode = mylist.CreatNode();
pi = new Int(i);
pnode->Linkinfo(pi);
mylist.InsertFront(pnode);
}
mylist.PrintList();
cout<<mylist.Length()<<endl; mylist.MakeEmpty();
cout<<mylist.Length()<<endl; List youlist;
char *str[6] = {"fjafjla","fjalla","ahfnj","xkk","fdjk","asdfg"};
String *ps = NULL;
for(i=0; i<6; ++i)
{
pnode = youlist.CreatNode();
ps = new String(str[i]);
pnode->Linkinfo(ps);
youlist.InsertRear(pnode);
} youlist.PrintList();
cout<<youlist.Length()<<endl; youlist.MakeEmpty();
cout<<youlist.Length()<<endl;
}
【C++】通用单链表的更多相关文章
- C实现通用数据结构--单链表
单链表概述 单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始. 从概念上讲,可以把链表想象成一系列连续的元素,然而,由于这些元素是动态分配的(C语言 ...
- 第一节 如何用Go实现单链表
一.概念介绍 下面这副图是我们单链表运煤车队. 每节运煤车就是单链表里的元素,每节车厢里的煤炭就是元素中保存的数据.前后车通过锁链相连,作为单链表运煤车,从1号车厢开始,每节车厢都知道后面拉着哪一节车 ...
- java 单链表反转
最近与人瞎聊,聊到各大厂的面试题,其中有一个就是用java实现单链表反转.闲来无事,决定就这个问题进行一番尝试. 1.准备链表 准备一个由DataNode组成的单向链表,DataNode如下: pub ...
- C++ "链链"不忘@必有回响之单链表
1. 前言 数组和链表是数据结构的基石,是逻辑上可描述.物理结构真实存在的具体数据结构.其它的数据结构往往在此基础上赋予不同的数据操作语义,如栈先进后出,队列先进先出-- 数组中的所有数据存储在一片连 ...
- 时间复杂度分别为 O(n)和 O(1)的删除单链表结点的方法
有一个单链表,提供了头指针和一个结点指针,设计一个函数,在 O(1)时间内删除该结点指针指向的结点. 众所周知,链表无法随机存储,只能从头到尾去遍历整个链表,遇到目标节点之后删除之,这是最常规的思路和 ...
- 单链表的C++实现(采用模板类)
采用模板类实现的好处是,不用拘泥于特定的数据类型.就像活字印刷术,制定好模板,就可以批量印刷,比手抄要强多少倍! 此处不具体介绍泛型编程,还是着重叙述链表的定义和相关操作. 链表结构定义 定义单链表 ...
- Java实现单链表的各种操作
Java实现单链表的各种操作 主要内容:1.单链表的基本操作 2.删除重复数据 3.找到倒数第k个元素 4.实现链表的反转 5.从尾到头输出链表 6.找到中间节点 7.检测链表是否有环 8.在 ...
- [LeetCode] Linked List Cycle II 单链表中的环之二
Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...
- c++单链表基本功能
head_LinkNode.h /*单链表类的头文件*/#include<assert.h>#include"compare.h"typedef int status; ...
随机推荐
- java.util.ComparableTimSort中的sort()方法简单分析
TimSort算法是一种起源于归并排序和插入排序的混合排序算法,设计初衷是为了在真实世界中的各种数据中能够有较好的性能. 该算法最初是由Tim Peters于2002年在Python语言中提出的. T ...
- A - Red and Black(3.2.1)(搜索)
A - Red and Black(3.2.1) Time Limit:1000MS Memory Limit:30000KB 64bit IO Format:%I64d & ...
- SharePoint创建一个简单的Visio Web部件图
SharePoint创建一个简单的Visio Web部件图 Visio有很多强大的Mash-up混聚功能,使它能够轻松集成到SharePoint 2010中. 1. 打开Visio 2010,创建新的 ...
- codetemplate
<?xml version="1.0" encoding="UTF-8" standalone="no"?><templa ...
- 0x59 单调队列优化DP
倍增DP太难啦心情好再回去做 poj1821 先让工匠按s排序,f[i][j]表示枚举到第i个工匠涂了j个木板(注意第j个木板不一定要涂) 那么f[i][j]可以直接继承f[i-1][j]和f[i][ ...
- P1025小飞侠的游园方案
描述 经过抽签选择,小智将军第一个进入考场. 菜虫:(身上散射出华贵(?)的光芒)欢迎你,第一位挑战者!! 小智:……(走到菜虫身后,关灯)女王陛下,虽然我们国家现在很富裕,但也请您不要浪费电来用这么 ...
- oracle连接数不够解决
ora-12516: TNS: 监听程序找不到符合协议堆栈要求的可用处理程 看到如上错误出现,就要查看是否是是数据库连接数被占满了 具体的查询sql如下: select count(*) from v ...
- Mysql数据的增删改
插入数据 INSERT 更新数据 UPDATE 删除数据 DELETE 再来回顾一下之前我们练过的一些操作,相信大家都对插入数据.更新数据.删除数据有了全面的认识.那么在mysql中其实最重要的不 ...
- 在无任何报错的情况下 pagehelper.startpage分页无效问题
问题原因:自从spring boot开始使用2.0x版本以上后,很多相应的依赖文件版本开始变化 该版本为spring-boot 1.4.1 <dependency> <groupId ...
- Absolute Horizontal And Vertical Centering In CSS
Quick CSS Trick: How To Center an Object Exactly In The Center Centering in CSS: A Complete Guide Ab ...