原创:C++实现的可排序的双向链表
学习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++实现的可排序的双向链表的更多相关文章
- MS - 1 - 把二元查找树转变成排序的双向链表
## 1. 把二元查找树转变成排序的双向链表 ## ### 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表. ### 要求不能创建任何新的结点,只调整指针的指向. 10 ...
- 1.把二元查找树转变成排序的双向链表[BST2DoubleLinkedList]
[题目]:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向. 比如将二元查找树 . 10 / \ 6 14 / \ / \ 4 8 12 16 转 ...
- 二元查找树转变成排序的双向链表之C#算法实现
此题为July在CSDN发布的微软编程面试100题中的第一题,觉得蛮有趣的,今天也拿过来玩玩,July的代码用的是C++实现,可能因为有指针的原因吧,感觉看起来相对比较容易理解整个的实现过程,而我,试 ...
- 【Data structure & Algorithm】把二元查找树转变成排序的双向链表
把二元查找树转变成排序的双向链表 题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表,要求不能创建任何新节点,只调整指针指向. 比如将二元查找树 10 / \ 6 ...
- 剑指offer26:将二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
1 题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 2 思路和方法 在二叉搜索树中,每个结点都有两个分别指向其左.右子树的 ...
- [个人原创]关于java中对象排序的一些探讨(三)
这篇文章由十八子将原创,转载请注明,并标明博客地址:http://www.cnblogs.com/shibazijiang/ 对对象排序也可以使用Guava中的Ordering类. 构造Orderin ...
- 1.Go语言copy函数、sort排序、双向链表、list操作和双向循环链表
1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 package main import "fmt" func main() ...
- 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 ...
- [置顶] 原创鼠标拖动实现DIV排序
先上效果图: 对比传统的排序,这是一个很不错的尝试,希望对大家有启发. 大家可以参考我的上一篇博文:http://blog.csdn.net/littlebo01/article/details/12 ...
随机推荐
- Disruptor底层源码解析(九)
架构图: 性能为什么这么牛逼: public void sendData(ByteBuffer data) { //1 在生产者发送消息的时候, 首先 需要从我们的ringBuffer里面 获取一个可 ...
- 如何在 WPF 中获取所有已经显式赋过值的依赖项属性
原文:如何在 WPF 中获取所有已经显式赋过值的依赖项属性 获取 WPF 的依赖项属性的值时,会依照优先级去各个级别获取.这样,无论你什么时候去获取依赖项属性,都至少是有一个有效值的.有什么方法可以获 ...
- 基于工作组消息队列高可用&msmq-wcf故障
场景: msmq 1# server故障手工切换到2# server,msmq-wcf service宿主服务重启后,无法成功读取消息,状似service不工作.无法监听到数据传输. 解决过程: 反复 ...
- GitHub上传文件问题总结
问题一:git warning: LF will be replaced by CRLF in 解决办法 在Git Bash中输入git add .时出现上述语句. 解决办法: 输入以下语句: $ g ...
- Java 之 web 相关概念
一.软件架构 1.C/S:客户端/服务器端 2.B/S:浏览器/服务器端(目前常用) 二.网络资源 1.静态资源 静态资源:所有用户访问后,得到的结果都是一样的,称为静态资源,静态资源可以直接被浏览器 ...
- python多进程间通信
这里使用pipe代码如下: import time from multiprocessing import Process import multiprocessing class D: @stati ...
- Python线性回归算法【解析解,sklearn机器学习库】
一.概述 参考博客:https://www.cnblogs.com/yszd/p/8529704.html 二.代码实现[解析解] import numpy as np import matplotl ...
- scrapy 用pycharm调试
1. 用pycharm打开scrapy项目,随便右击一个.py文件,选择Debug "***" 2. pycharm 右上角点击刚才debug的文件,选择Edit Configur ...
- Zabbix-报警之微信(Wechat alert)告警
1.前言 Zabbix告警发送是监控系统的重要功能之一.Zabbix可以通过多种方式把告警信息发送到指定人,常用的有邮件,短信报警方式,但是越来越多的企业开始使用zabbix结合微信作为主要的告警方式 ...
- (备忘)cron表达式的用法
一.结构 cron表达式用于配置cronTrigger的实例,实现任务调度的功能. Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格 ...