在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. python实现高速排序算法(两种不同实现方式)

    # -*- coding: utf-8 -*- """ Created on Fri May 16 17:24:05 2014 @author: lifeix " ...

  2. axis2调用webservice教训

    总结教训,axis2client调用WS接口时url不能加?wsdl,而用cxf调用时则要加上. 今天用axis2的RpcServerClient调用https的webservice接口,在设置完op ...

  3. [JavaEE] DWR框架实现Ajax

    Ajax是时下比较流行的一种web界面设计新思路,其核心思想是从浏览器获取XMLHttp对象与服务器端进行交互. DWR(Direct Web Remoting)就是实现了这种Ajax技术的一种web ...

  4. [源码管理] ubuntu中svn简明用法:服务器搭建+客户端使用

    本文是对网络上前人的优秀文章加以实践验证后所整理(修正或补充) 第一部分:svn服务器搭建(主要是四步走) 参考:http://www.son1c.cn/show/920.html 一,安装Subve ...

  5. Queue 与List、LinkedList与 ArrayList 区别

    List 是一个接口,不能实例化,通过实例化ArrayList 或者LinkedList来调用:List list = new ArrayList(); |--List: 元素是有序的(怎么存的就怎么 ...

  6. NOIP 2012 D1T1 Vigenère密码

    嗯嗯 一道找规律的题.... 真佩服那些把表打出来的人 //By SiriusRen #include <cstdio> #include <cstring> using na ...

  7. SQLServer int转float

    例: select 2/4  会得到0 改为 select 2/4.0 则会得到0.500000 也同时达到了int转float的效果

  8. 重温前端基础之-css浮动与清除浮动

    文档流的概念指什么?有哪种方式可以让元素脱离文档流? 文档流,指的是元素排版布局过程中,元素会自动从左往右,从上往下的流式排列.并最终窗体自上而下分成一行行,并在每行中按从左到右的顺序排放元素.脱离文 ...

  9. App Store兼容性问题

    app下载出现兼容性问题  项目支持9.0以上的系统 但是10.3的iphone5下载的一直是老版本app  下载时提示不兼容 导致无法正常使用 解决办法: 修改Build-Settings-> ...

  10. SQL SERVER数据库状态

    一个SQL SERVER数据库会处于很多种状态,例如 ONLINE .RESTORING .RECOVERING .RECOVERY_PENDING  .SUSPECT.EMERGENCY .OFFL ...