学习C++有一周了,今天用C++设计了一个双向链表,这个链表有排序功能,默认按升序排列,接受的参数可以是数字,也可以是字符串。现在把自己写的代码,分享出来。如果链表中接受的对象为Lexeme,可以用于存储中文分词机械化分词后的结果集。

QuickSortSet.h

#ifndef DOUBLE_LINK_H_INCLUDED
#define DOUBLE_LINK_H_INCLUDED
#include<iostream>
class QuickSortSet
{

//双向链表节点
public: class Node
{
public:
Node* next;
public:
Node* pre;
const void* value;
Node(const void* val)
{
value = val;
next = pre = nullptr;
}
};
public:

//constructor
QuickSortSet(int qs = CAPACITY);
//析构函数
~QuickSortSet();
//赋值运算符
QuickSortSet& operator=(const QuickSortSet& qs)
{
return *this;
}

//链表的大小
int size();

//比较节点值的大小,仅限于数字和字符串
int compare(const void* a,const void* b);

//将"value"插入到链表,成功返回0,否则返回-1
int insert(const void *pval);

//返回链表的第一个元素
const void* peekFirst();
//返回链表的最后一个元素
const void* peekLast();

//取出链表的第一个元素
const void* pollFirst();
//取出链表的最后一个元素
const void* pollLast();

bool isEmpty()
{
return count == 0;
}
bool isFull()
{
return count == qSize;
}

Node* getHead()
{
return head;
}
Node* getTail()
{
return tail;
}

private:
enum {CAPACITY = 1 << 30 -1};
const int qSize;
int count;

//链表头部和尾部
Node* head;
Node* tail;
};
#endif // DOUBLE_LINK_H_INCLUDED

QuickSortSet实现:

#include<iostream>
#include<cctype>
#include<cstring>
#include "double_link.h"
using namespace std;

/**
* 构造函数,默认容量为CAPACITY
*/
QuickSortSet::QuickSortSet(int qs):qSize(qs){
head = tail = nullptr;
count = 0;
}
/**
* 析构函数,默认容量为CAPACITY
*/
QuickSortSet::~QuickSortSet(){
QuickSortSet::Node* temp;
while(head){
temp = head;
head = head->next;
delete temp->value;
delete temp;
}
}

/**
* 返回链表的大小
* \return count
*/
int QuickSortSet::size()
{
return count;
}
/**
* 比较节点值的大小,仅限于数字和字符串
*/
int QuickSortSet::compare(const void* a,const void* b)
{
if (isdigit(*(int*)a))
{
return (*(int*)a) - (*(int*)b);
}
else
{
int i = 0,j = 0;
while (((const char*)a)[i] && ((const char*)b)[j])
{
if (((const char*)a)[i] - ((const char*)b)[j] != 0)
{
return ((const char*)a)[i] - ((const char*)b)[j];
}
i++,j++;
}
if (strlen((const char*)a) == i && strlen((const char*)b) == j)
{
return 0;
}
else if (strlen((const char*)a) == i)
{
return 1;
}
else
{
return -1;
}

}

}

/**
* 将"value"插入到链表,成功返回0,否则返回-1
*/
int QuickSortSet::insert(const void *pval)
{
Node* n;
//1.链表为空时
if (isEmpty())
{
n = new Node(pval);

head = tail = n;
count ++;
return 1;
}
if (isFull()) {return -1;}

//2.如果链表不为空,进行比较,确定位置
if (compare(head->value,pval) > 0) //在head前面
{
n = new Node(pval);
n->next = head;
head->pre = n;
head = n;
count++;
return 1;
}
else if (compare(tail->value,pval) < 0) //tail后面
{
n = new Node(pval);
tail->next = n;
n->pre = tail;
tail = n;
count++;
return 1;
}
else //位于head和tail之间的某一个位置
{
Node* index = tail;
while(compare(index->value,pval) > 0)
{
index = index->pre;
}
n = new Node(pval);

n->pre = index;
n->next = index->next;
index->next->pre = n;
index->next = n;

count++;
return 1;
}
return -1;
}
/**
* 返回链表的第一个元素
*/
const void* QuickSortSet::peekFirst()
{
return head == NULL ? NULL : head->value;
}
/**
* 取出链表的第一个元素
*/
const void* QuickSortSet::pollFirst()
{
Node* temp = head;
const void* value = temp->value;
head = head->next;
delete temp->value;
delete temp;
return value;
}

/**
* 返回链表的最后一个元素
*/
const void* QuickSortSet::peekLast(){
return tail == nullptr ? nullptr : tail->value;
}

/**
* 取出链表的最后一个元素
*/
const void* QuickSortSet::pollLast(){
Node* temp = tail;
const void* value = temp->value;
tail = tail->pre;
delete temp->value;
delete temp;
return value;
}

测试类:

#include<cstdlib>
#include<iostream>
#include "heap.h"
#include "double_link.h"
#include "time.h"
#include<fstream>
#define DEBUG 1
#define SIZE 5
#define LINE 10000000
using namespace std;
void testNum();
void testStr();
//void testHeap();
//void createFile();
int main()
{
#if DEBUG
//testNum();
testStr();
#endif // DEBUG
//createFile(); //生成随机数文件
// testHeap();
}
#if DEBUG
void testNum()
{
QuickSortSet q = QuickSortSet();

int num = 12;
q.insert(&num);

const int num1 = 3;
q.insert(&num1);

const int num2 = 9;
q.insert(&num2);

QuickSortSet::Node* node = q.getHead();
while(node){
cout << *((int*)node->value) << endl;
node = node->next;
}
}
void testStr()
{
QuickSortSet q = QuickSortSet();

q.insert("abc");
q.insert("abce");
q.insert("abcd");
q.insert("abcf");

QuickSortSet::Node* node = q.getHead();

while(node){
cout << (const char*)node->value << endl;
node = node->next;
}
}
#endif // DEBUG

/**
* 1.生成随机数文件;
* 2.读取前SIZE行,构造小根堆;
* 3.依次读取剩余的行,对读到的每行数据,如果比堆顶元素大,替换之,然后调整小根堆;
* 4.读取结束后,执行堆排序。
*/
void testHeap()
{

clock_t start,finish;
double duration;//耗时时间
start = clock();

ifstream inFile;
inFile.open("E:\\var\\logs\\nums.txt");

int nums[SIZE];
int index = 0;
char num[1024] = {0};
while (inFile.getline(num,sizeof(num)))
{
nums[index++] = atoi(num);
if (index == SIZE)
{
break;
}
}
createMinHeap(nums,SIZE);//读取前SIZE行,构造小根堆

int temp;
while (inFile.getline(num,sizeof(num)))
{
temp = atoi(num);
if (temp > nums[0])
{
nums[0] = temp;
adjustment(0);
}
}//依次读取剩余的行,对读到的每行数据,如果比堆顶元素大,替换之,然后调整小根堆

heapSort();//读取结束后,执行堆排序

finish = clock();
duration = (double)((finish - start) / CLOCKS_PER_SEC);
cout << "耗时 " << duration << "s." << endl;
for (int i = 0; i < SIZE; i++)
{
cout << nums[i] << " ";
}
}
/**
* 产生随机数文件
*/
void createFile()
{
ofstream outFile;
outFile.open("E:\\var\\logs\\nums.txt");
srand((unsigned)time(NULL));
for (int i = 0; i <= LINE; i++)
{
outFile << rand() << endl;
}
}
void safeDelete(){

}

输出结果:

abcd

abce

abcf

abc

原创:C++实现的可排序的双向链表的更多相关文章

  1. MS - 1 - 把二元查找树转变成排序的双向链表

    ## 1. 把二元查找树转变成排序的双向链表 ## ### 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表. ### 要求不能创建任何新的结点,只调整指针的指向. 10       ...

  2. 1.把二元查找树转变成排序的双向链表[BST2DoubleLinkedList]

    [题目]:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向. 比如将二元查找树 . 10 / \ 6 14 / \ / \ 4 8 12 16 转 ...

  3. 二元查找树转变成排序的双向链表之C#算法实现

    此题为July在CSDN发布的微软编程面试100题中的第一题,觉得蛮有趣的,今天也拿过来玩玩,July的代码用的是C++实现,可能因为有指针的原因吧,感觉看起来相对比较容易理解整个的实现过程,而我,试 ...

  4. 【Data structure & Algorithm】把二元查找树转变成排序的双向链表

    把二元查找树转变成排序的双向链表 题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表,要求不能创建任何新节点,只调整指针指向. 比如将二元查找树 10 /       \ 6       ...

  5. 剑指offer26:将二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

    1 题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 2 思路和方法 在二叉搜索树中,每个结点都有两个分别指向其左.右子树的 ...

  6. [个人原创]关于java中对象排序的一些探讨(三)

    这篇文章由十八子将原创,转载请注明,并标明博客地址:http://www.cnblogs.com/shibazijiang/ 对对象排序也可以使用Guava中的Ordering类. 构造Orderin ...

  7. 1.Go语言copy函数、sort排序、双向链表、list操作和双向循环链表

    1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 package main import "fmt" func main() ...

  8. 1.Go-copy函数、sort排序、双向链表、list操作和双向循环链表

    1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 ? 1 2 3 4 5 6 7 8 9 10 11 12 package main   imp ...

  9. [置顶] 原创鼠标拖动实现DIV排序

    先上效果图: 对比传统的排序,这是一个很不错的尝试,希望对大家有启发. 大家可以参考我的上一篇博文:http://blog.csdn.net/littlebo01/article/details/12 ...

随机推荐

  1. .Net Core-类库中创建CodeFirst

    本文仅用来学习记录. 搭建项目架构的时候,需要在类库中进行CodeFirst数据迁移   1.在项目的解决方案中,添加类库ERPFrame.Model 2.在类库项目中 添加实体模型和数据上下文 其中 ...

  2. 转 如何在调用WCF服务之前弹出一个确认对话框

    自定义InteractiveChannelInitializer(InvocationConfirmationInteractiveChannelInitializer)定义如下.我们在BeginDi ...

  3. 视频质量评估 之 VMAF

    VMAF 方法: 基本想法: 面对不同特征的源内容.失真类型,以及扭曲程度,每个基本指标各有优劣.通过使用机器学习算法(支持向量机(Support Vector Machine,SVM)回归因子)将基 ...

  4. React Native 开发豆瓣评分(二)路由配置

    路由管理使用官方推荐的 React Navigation; 配置环境 安装相关依赖 yarn add react-navigation react-native-gesture-handler Lin ...

  5. 嵌入式处理器通过UART实现scanf和printf

    #include <stdint.h> #include <stdarg.h> extern int vsscanf(const char *, const char *, v ...

  6. mysql 的使用

    1. 安装 https://dev.mysql.com/downloads/mysql/ 2. 配置 $ vim ~/.bash_profile $ export PATH=$PATH:/usr/lo ...

  7. IDEA设置项目文件自动Add到Svn/Git

    1)配置自动Add 2)将未添加的文件添加到本地 3)取消已经添加的文件

  8. SQL SERVER-Extendevent系统视图

    --获得扩展事件的事件 select name,description from sys.dm_xe_objects where object_type='event' order by name - ...

  9. [http] http body中chunked数据的编码格式

    一 我们知道,http response的body可以使用chunked编码.这个时候不需要显示的 指定content-length来标记结尾. 如: 我们可以见到编码的chunked字样,并且没有看 ...

  10. 解决zabbix_web显示中文乱码问题

    zabbix图形中文显示设置 如果想将zabbix的界面改成中文,点击类似于管理员头像,可以直接修改 检测中---图形,却显示乱码,这个问题是由于zabbix的web端没有中文字库,我们最需要把中文字 ...