在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. 消除ADB错误“more than one device and emulator”的方法

    当我连着手机充电的时候,启动模拟器调试,运行ADB指令时,报错. C:\Users\gaojs>adb shell error: more than one device and emulato ...

  2. leetCode 20.Valid Parentheses (有效的括号) 解题思路和方法

    Valid Parentheses  Given a string containing just the characters '(', ')', '{', '}', '[' and ']', de ...

  3. 辨异 —— Java 中的抽象类和接口

    接口优于抽象类.-- <Effective Java>(Item 18) 0. 语法区别 抽象类允许给出某些方法的实现,接口不允许: 为了实现由抽象类定义的类型(type),类必须成为抽象 ...

  4. php word转pdf

    我们知道,PHP语言的合理运用可以帮助我们实现导出Word文档的功能.今天我们将为大家介绍PHP处理Word转PDF的相关实现方法. PHP关键字this指向当前对象指针 PHP self关键字指向类 ...

  5. iOS数组越界

    数组越界就是假如你的下标总数现在为32个,然后你在下一秒又执行了一个方法要从50个数据里进行赋值啊筛选之类的,而你此时数组里的值为32个,50的数据还没有请求到,往往会出现数组越界的崩溃信息,大概是这 ...

  6. Oracle数据库学习1------数据库安装及客户端配置

    1.注册Oracle账户: 注册地址:https://login.oracle.com/mysso/signon.jsp 注意:注册的时候尽量使用外国的邮箱,因为使用国内的邮箱可能收不到Oracle发 ...

  7. Java 系列之spring学习--注解(三)

    一.注解 使用注解之前要开启自动扫描功能 <?xml version="1.0" encoding="UTF-8"?> <beans xmln ...

  8. JS中数组的一些笔记

    今天工作时碰到一个需求,有两个数组arrayChild, arrayFather, 要求: 1.往数组arrayChild中放入一个元素: 2.将当前的数组arrayChild放入arrayFathe ...

  9. 了解jQuery的$符号

    $是什么? 可以使用typeof关键字来观察$的本质. console.log(type of $); //输出结果为function 因此可以得出结论,$其实就是一个函数.$(); 只是根据所给参数 ...

  10. windows安装pyspider

    基本环境 python2.7 win7 64bit 问题 Microsoft Visual C++ 10.0 is required Microsoft Visual C++ Compiler for ...