在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++】通用单链表的更多相关文章

  1. C实现通用数据结构--单链表

    单链表概述 单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始. 从概念上讲,可以把链表想象成一系列连续的元素,然而,由于这些元素是动态分配的(C语言 ...

  2. 第一节 如何用Go实现单链表

    一.概念介绍 下面这副图是我们单链表运煤车队. 每节运煤车就是单链表里的元素,每节车厢里的煤炭就是元素中保存的数据.前后车通过锁链相连,作为单链表运煤车,从1号车厢开始,每节车厢都知道后面拉着哪一节车 ...

  3. java 单链表反转

    最近与人瞎聊,聊到各大厂的面试题,其中有一个就是用java实现单链表反转.闲来无事,决定就这个问题进行一番尝试. 1.准备链表 准备一个由DataNode组成的单向链表,DataNode如下: pub ...

  4. C++ "链链"不忘@必有回响之单链表

    1. 前言 数组和链表是数据结构的基石,是逻辑上可描述.物理结构真实存在的具体数据结构.其它的数据结构往往在此基础上赋予不同的数据操作语义,如栈先进后出,队列先进先出-- 数组中的所有数据存储在一片连 ...

  5. 时间复杂度分别为 O(n)和 O(1)的删除单链表结点的方法

    有一个单链表,提供了头指针和一个结点指针,设计一个函数,在 O(1)时间内删除该结点指针指向的结点. 众所周知,链表无法随机存储,只能从头到尾去遍历整个链表,遇到目标节点之后删除之,这是最常规的思路和 ...

  6. 单链表的C++实现(采用模板类)

    采用模板类实现的好处是,不用拘泥于特定的数据类型.就像活字印刷术,制定好模板,就可以批量印刷,比手抄要强多少倍! 此处不具体介绍泛型编程,还是着重叙述链表的定义和相关操作.  链表结构定义 定义单链表 ...

  7. Java实现单链表的各种操作

    Java实现单链表的各种操作 主要内容:1.单链表的基本操作 2.删除重复数据 3.找到倒数第k个元素   4.实现链表的反转   5.从尾到头输出链表 6.找到中间节点 7.检测链表是否有环 8.在 ...

  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 ...

  9. c++单链表基本功能

    head_LinkNode.h /*单链表类的头文件*/#include<assert.h>#include"compare.h"typedef int status; ...

随机推荐

  1. iOS8 tableView的Cell高度自适应开发

    1.在- (void)viewDidLoad中设置: //估计高度为81 self.tableView.estimatedRowHeight = 81.0f; //自适应高度 self.tableVi ...

  2. Hadoop Web项目--Friend Find系统

    项目使用软件:Myeclipse10.0,JDK1.7,Hadoop2.6,MySQL5.6.EasyUI1.3.6.jQuery2.0,Spring4.1.3. Hibernate4.3.1,str ...

  3. linux下udev简介【转】

    本文转载自:http://blog.csdn.net/skyflying2012/article/details/9364555 一.关于Udev u即user space,dev是device,通过 ...

  4. 使用getopt命令解析shell脚本的命令行选项 【转】

    本文转载自:http://yejinxin.github.io/parse-shell-options-with-getopt-command 在之前的一篇文章中,介绍了如何利用shell内置的get ...

  5. [HTML5] 让IE支持HTML5的方法

    越来越多的站点开始使用 HTML5 标签,但是目前的情况是还有很多人在使用IE6.IE7.IE8.为了让所有浏览者都可以正常的访问,解决方案有下面两个: 1.为网站创建多套模板,通过程序对User-A ...

  6. BPM中字段查重,C#Ajac调用示例

    BPM中字段查重记录: 这也算是一个C#调用Ajax的示例吧,如果是异步加载的话async: false去掉就可以了. 需求:比如现在要录入一些信息,但是,有一个字段不能重复,BPM表都是自己生成的, ...

  7. 安装windwos7 iis 出现错误,并非所有都成功更改的解决办法

    1.首先排除网上说的 安装的WIN7是精简版的问题,我这个是旗舰版,以前是正常安装IIS的,后来程序问题我卸载了,就安装不上了 2.网上说的修改什么UAC权限,也是胡扯,因为默认都是最低的 3.排除网 ...

  8. Android stroke 边框线 某一边

    有时候需要给View加边框线,我们经常是四边一起加,就像这样: <shape xmlns:android="http://schemas.android.com/apk/res/and ...

  9. AVD的Hardware选项

    最近学习开发游戏,需要GLES2.0使用,使用Android虚拟机调试一直报错闪退.百度说Android 4.0及以后的版本[使用API15及以上]),已经支持GLES2.0,需要在HardWare选 ...

  10. RAP开发入门-运行过程简析(三)

    今天通过标准的RAP程序来简单分析下RAP的启动过程 1.新建一个标准的rap plugin-in 项目: 得到的项目结构大概如下: run confi..->..add bundle(配置好b ...