head_LinkNode.h
/*单链表类的头文件*/
#include<assert.h>
#include"compare.h"
typedef int status;//整形的状态值
#define OK 1;//status参数
#define ERROR 0;//status参数
template <class type>
class LinkNode
{
protected:
LinkNode* head;
public:
void out();//输出函数
LinkNode()//对象初始化
{
data=0;
next=NULL;
head=NULL;
}
void menu();//菜单
LinkNode<type> operator=(LinkNode<type> right);
private:
void sort();//排序
void putin(int a);//输入函数
status insert(int a,type b);//插入函数
void clear();//清空
void inversion();//倒置节点
status delc(type a);//删除所有指定data节点
status find(type a);//查找(通过参数号)
status del(int a);//删除函数(指定位号)
status locateELem(type e,status (*compare)(type,type));
//成员变量
type data;
LinkNode<type> *next;
static int n;//当前单链表元素个数
//成员变量
typedef LinkNode * nodepoint;//指向节点的指针(在类内不用给出类型 在对象生成时类型确定)
};
template <class type>
int LinkNode<type>::n=0;//只能在类外初始化
/*
功能:运算符重载
方法:先置空 左边 后通过滑动不断用右边赋值左边
*/
template <class type>
LinkNode<type> LinkNode<type>::operator=(LinkNode<type> right)
{
nodepoint p=NULL;//指向左边的单链表当前节点为空
nodepoint rp=right.head;//指向右边的单链表当前节点
nodepoint s;//在赋值过程中左边可能需要的新节点
if(this!=&right)
{
clear();//清空左边
while(rp)
{
s= new LinkNode;
assert(s!=0);
s->data=rp->data;
if(!head)
head=s;
else
p->next=s;
p=s;
rp=rp->next;
}
if(p)
p->next=NULL;
}
return *this;
}
/*
功能:在第a个节点前插入一个节点
方法:先判断一种特殊情况(在头部插入) 并且特殊处理 对于普通情况采用先用循环滑动到指定节点前再做处理
*/
template <class type>
status LinkNode<type>::insert(int a,type b)
{
int j=1;//表示当前单链表的序号
nodepoint p=head;//从第一个节点开始循环;
nodepoint s;//用于插入
if(a==1)//在头部插入情况
{
s= new LinkNode;
assert(s!=0);
(*s).data=b;
(*s).next=head;
head=s;
n++;
return OK;
}
if(a>n)
return ERROR;
while(p&&j<a-1)//从头节点开始滚动到指定插入点的前一个节点
{
p=p->next;
j++;
}
s= new LinkNode;
assert(s!=0);
s->data=b;
s->next=p->next;
p->next=s;
n++;
char u='y';
cout<<"是否排序?(y or n?)"<<endl;
cin>>u;
if(u=='y')
sort();
return OK;
}
/*
功能:输入
方法:通过插入和倒置函数实现
*/
template <class type>
void LinkNode<type>::putin(int a)
{
clear();
type b;
cout<<"输入开始"<<endl;
for(;a>0;a--)
{
cin>>b;
insert(1,b);
}
inversion();
}
/*
功能:输出单链表
方法:通过next指针不断滑动输出节点DATA
*/
template <class type>
void LinkNode<type>::out()
{
nodepoint p=head;
cout<<"当前单链表"<<endl;
while(p)
{
cout<<p->data<<'\t';
p=p->next;
}
cout<<endl;
}
/*
功能:删除指定节点(指定位号)
方法:滑动前驱节点和当前结点到指定位号 使前驱结点直接连接后继节点
*/
template <class type>
status LinkNode<type>::del(int a)
{
nodepoint p=head;//当前节点
nodepoint r=NULL;//前驱节点
int i=1;
if(a>n)
return ERROR;
if(a==1)//特殊处理删除第一个节点
{
head=p->next;
p=NULL;
n--;
return OK;
}
while(p&&i!=a)
{
r=p;
p=(*p).next;
i++;
}
if(a==n)//特殊处理删除尾节点
{
r->next=NULL;
p=NULL;
n--;
return OK;
}
r->next=p->next;
n--;
p=NULL;
return OK;
}
/*
功能:返回查找的节点
方法:滑动当前结点到指定位号 返回data
*/
template <class type>
status LinkNode<type>::find(type a)
{
nodepoint p=head;
int i=1;
while(p)
{
if(a==p->data)
{
cout<<a<<"是单链表中的第"<<i<<"个节点"<<endl;
return OK;
}
i++;
p=p->next;
}
return ERROR;
}
/*
功能:清空单链表
方法:以单链表节点数n为基准通过不断的调用del函数删除第一个节点从而清空单链表
*/
template <class type>
void LinkNode<type>::clear()
{
int i=1;
while(head!=NULL&&i<=n)
{
del(1);
i--;
}
n=0;
}
/*
功能:倒置单链表
方法:先把next指针从链向后变为链向前 然后通过变换前驱、当前、后继的指向重复变换next 及完成倒置
*/
template <class type>
void LinkNode<type>::inversion()
{
if(n==0)
return;
nodepoint p=head;
nodepoint r=NULL;
nodepoint q=p->next;
while(p)
{
p->next=r;
r=p;
p=q;
if(q)//保证后继指针q不会出表
q=p->next;
}
head=r;
}
/*
功能:删除所有指定data节点
方法:从头滚动到链尾找到与参数a相等的data就利用del函数删除这个节点
*/
template <class type>
status LinkNode<type>::delc(type a)
{
nodepoint p=head;
int i=1;
int c=ERROR;
while(i<=n)
{
if(p->data==a)
{
del(i);
i=i-1;//删除后从上一位开始找
c=OK;
}
p=p->next;
i++;
}
return c;
}
/*菜单*/
template <class type>
void LinkNode<type>::menu()
{
char p='y';
int a;
for(;;)
{
cout<<"****************************处理菜单****************************"<<endl;
cout<<"1.输入"<<endl;
cout<<"2.输出"<<endl;
cout<<"3.插入"<<endl;
cout<<"4.倒置"<<endl;
cout<<"5.查找"<<endl;
cout<<"6.删除指定位号节点"<<endl;
cout<<"7.删除指定元素在单链表中的所有节点"<<endl;
cout<<"8.清空单链表"<<endl;
cout<<"9.排序"<<endl;
out();
cout<<"****************************处理菜单****************************"<<endl;
cout<<"请选择:";
cin>>a;
switch(a)
{
case 1:{
int b;
cout<<"请输入你要输入节点的个数"<<endl;
cin>>b;
putin(b);
};break;
case 2:{
out();
};break;
case 3:{
type c;
int y;
cout<<"请输入你要插在那位节点前面"<<endl;
cin>>y;
cout<<"请输入你要插入的元素"<<endl;
cin>>c;
if(insert(y,c))
cout<<"OK"<<endl;
else
cout<<"ERROR";
};break;
case 4:{
inversion();
};break;
case 5:{
type y;
cout<<"请输入你要查找的数据"<<endl;
cin>>y;
if(find(y))
cout<<"OK"<<endl;
else
cout<<"ERROR"<<endl;
};break;
case 6:{
int y;
cout<<"请输入你要删除的节点位号"<<endl;
cin>>y;
if(del(y))
cout<<"OK"<<endl;
else
cout<<"ERROR";
};break;
case 7:{
type y;
cout<<"请输入你要删除的元素"<<endl;
cin>>y;
if(delc(y))
cout<<"OK"<<endl;
else
cout<<"ERROR";
};break;
case 8:{
clear();
};break;
case 9:{
sort();
};break;
}
getchar();//接受回车
cout<<"是否继续处理?(n退出)"<<endl;
p=getchar();
system("cls");
if(p=='n')
break;
}
}
/* 功能:排序
方法:使用冒泡排序通过不断滚动对比data交换data达到排序目的
*/
template <class type>
void LinkNode<type>::sort()
{
nodepoint p=head;
nodepoint q=p->next;
type s;
for(int i=0;i<n;i++)
{
p=head;
q=p->next;
for(int c=0;c<n-i-1;c++)
{
if(p->data>q->data)
{
s=p->data;
p->data=q->data;
q->data=s;
}
p=p->next;
q=p->next;
}
}
}
LinkNode.cpp
#include"head_LinkNode.h"
#include<iostream>
#include<string>
using namespace std;
int main()
{
int a;
char p='y';
for(;;)
{
cout<<"请输入你要处理的数据类型(char(1) int(2) float(3) double(4) )"<<endl;
cin>>a;
switch(a)
{
case 1: {LinkNode<char> sq;
sq.menu();
}break;
case 2: {LinkNode<int> sq;
sq.menu();
}break;
case 3: {LinkNode<float> sq;
sq.menu();
}break;
case 4: {LinkNode<double> sq;
sq.menu();
}break;
default: cout<<"错误请重新输入"<<endl;
}
cout<<"是否继续处理其他类型顺序表? 请输入 任意字符继续或n结束"<<endl;
getchar();
p=getchar();
if(p=='n')
break;
}
system("pause");
}
c++单链表基本功能的更多相关文章
-
Java 实现简答的单链表的功能
作者:林子木 博客网址:http://blog.csdn.net/wolinxuebin 參考网址:http://blog.csdn.net/sunsaigang/article/details/5 ...
-
python--自己实现的单链表常用功能
最近一个月,就耗在这上面吧. 很有收获的. # coding = utf-8 # 单向链表 class Node: def __init__(self, new_data): self.data = ...
-
python实现单链表及链表常用功能
单链表及增删实现 单链表高级功能实现:反序,找中间结点,检测环等 参考: https://github.com/wangzheng0822/algo
-
C语言单链表实现19个功能完全详解
谢谢Lee.Kevin分享了这篇文章 最近在复习数据结构,想把数据结构里面涉及的都自己实现一下,完全是用C语言实现的. 自己编写的不是很好,大家可以参考,有错误希望帮忙指正,现在正处于编写阶段,一共将 ...
-
java实现单链表的增删功能
JAVA 实现单链表的增删功能 package linked; class LinkedTable{ } public class LinkedTableTest { public static vo ...
-
数据结构:单链表结构字符串(python版)添加了三个新功能
#!/urs/bin/env python # -*- coding:utf-8 -*- #异常类 class stringTypeError(TypeError): pass #节点类 class ...
-
数据结构C语言版--单链表的基本功能实现
/* * 构造一个链式存储的线性表(当输入9999时,结束构造过程),然后输出该线性表 * 并统计该线性链表的长度 . *注:new和delete是C++的运算符 malloc和free是C++/C的 ...
-
单链表的C++实现(采用模板类)
采用模板类实现的好处是,不用拘泥于特定的数据类型.就像活字印刷术,制定好模板,就可以批量印刷,比手抄要强多少倍! 此处不具体介绍泛型编程,还是着重叙述链表的定义和相关操作. 链表结构定义 定义单链表 ...
-
分离的思想结合单链表实现级联组件:CascadeView
本文介绍自己最近做省市级联的类似的级联功能的实现思路,为了尽可能地做到职责分离跟表现与行为分离,这个功能拆分成了2个组件并用到了单链表来实现关键的级联逻辑,下一段有演示效果的gif图.虽然这是个很常见 ...
随机推荐
-
atitit.闭包的概念与理解attilax总结v2 qb18.doc
atitit.闭包的概念与理解attilax总结v2 qb18.doc 1.1. 闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了*变量的函数.1 2. #---- ...
-
说不尽的MVVM(4) – 发号施令的Command
知识预备 阅读本文,我假定你具备以下知识: C# WPF基础知识 知道WPF的命令 WPF相对WinForm加了一种Command的机制,对用户的操作进行更加灵活的处理,相信很多朋友知道并用过Rout ...
-
JDBC连接池的简单实现
首先解释一下,我在做自己android发育.java web这是我的弱点,就在最近,京东云免费,因此,要折腾几.有一点经验,特别是作为共享. 假设内容的文章是错,还请高手指正. 我在这里web结束,需 ...
-
spark 1.6 完全分布式平台搭建
软件环境: scala-2.11.4.tgz spark-1.6.2-bin-hadoop2.6.tgz 操作步骤: 一. 安装scala 1. 解压scala (tar –zxvf filena ...
-
mybatis_SQL映射(4)鉴别器
摘录自:http://blog.csdn.net/y172158950/article/details/17505739 鉴别器:有时一个单独的数据库查询也许返回很多不同(但是希望有些关联)数据类型的 ...
-
android 滑动分页
import android.app.ListActivity;import android.os.Bundle;import android.os.Handler;import android.vi ...
-
ioremap_nocache() 函数的使用【转】
本篇文章主要是在ioremap_nocache函数说明的基础上进行整理,加入该函数的用法简介. 函数原型 void __iomem * ioremap_nocache (unsigned long o ...
-
java基础(三)-----java的三大特性之多态
面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...
-
特性(attribute)
一.什么是特性? 特性(attribute)是被指定给某一声明的一则附加的声明性信息. 在C#中,有一个小的预定义特性集合.在学习如何建立我们自己的定制特性(custom attributes)之前, ...
-
C++中const关键字的使用方法,烦透了一遍一遍的搜,总结一下,加深印象!!!
之前一直在学习C/C++,关于const的使用,这里出现一点,那里出现一点.知识用时方恨少,这一段时间正好各种笔试题,其中关于const的用法也是层出不穷,所以疲于在书本上各种翻,这里汇总一下,加深自 ...