学习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. Webform中的前后端分离

    Webform常用的开发方式 (1)运用服务器端控件的aspx页面 (2)一般处理程序+html静态页面+Ajax(所谓的前后端分离) (3)一般处理程序+html模板引擎   这里简单记录html+ ...

  2. elasticsearch授权访问

    1.search guard插件 https://www.cnblogs.com/shifu204/p/6376683.html 2.Elasticsearch-http-basic 不支持es5,忽 ...

  3. 【转载】C#中string类使用Substring方法截取字符串

    在C#的字符串操作过程中,截取字符串是一种常见的字符串操作,可使用string类的Substring方法来完成字符串的截取操作,该方法支持设定截取的开始位置以及截取的字符串长度等参数,Substrin ...

  4. 当ajax都完成后执行方法

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  5. there is no route defined for key Agreement(react native bug记录)

    调试react native的项目有一个报错: there is no route defined for key XXXX 它发生在我调试TabNavigator选项卡路由器的时候,我把如下代码的A ...

  6. python 笔记一

    1. is 和 ==区别 is 判断是否是一个ID(内存中的数据是否是同一个), == 判断内容是否一致. 2.python 常量池包括 1.短整型的-5~256 2.字符串的数字.大小写字母随意组合 ...

  7. 【Java】锁机制

    参考 https://blog.csdn.net/varyall/article/details/79698145 <深入理解Java虚拟机> 锁状态:无锁.偏向锁.轻量级锁.重量级锁(具 ...

  8. 微信公众号&小程序 -- 获取并解密用户数据(获取openId、unionId)

    本文转自https://my.oschina.net/u/3235888/blog/832895 前言 微信小程序API文档:https://mp.weixin.qq.com/debug/wxadoc ...

  9. 【HCIA Gauss】学习汇总-数据库管理-2

    数据库管理目标:稳定 安全 数据一致性 系统高性能 数据库管理员 数据库管理范围 :数据库管理对象1.物理设计工作 2.物理实现工作 对象是指 :数据库里 存储和指向数据的各种概念和结构的总称 对象管 ...

  10. HTML&CSS基础-样式的继承

    HTML&CSS基础-样式的继承 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.HTML源代码 <!DOCTYPE html> <html> & ...