Link.h

#ifndef _LINK_0411
#define _LINK_0411
#include <string>
#include <iostream>
//定义数据类型为整型
typedef int ElementType;
//定义结点
struct Node
{
ElementType data;
Node * next;
};
//带头结点链表
class Link
{
public:
Link();
~Link();
//选择排序
void select_sort();
//冒泡排序
void bubble_sort();
//头部插入
void insert_head(ElementType data);
//尾部插入
void insert_tail(ElementType data);
//查找结点,返回序号,如果不存在返回-1
int find(ElementType data);
//删除结点
bool delete_node(int pos);
//逆置
void reverse();
//打印链表
void display();
//打印提示信息
void printhelp();
//返回长度
int size();
private:
//头结点指针
Node * pHead;
//链表长度
size_t iSize;
};
#endif

Link.cpp

 #include "Link.h"

 Link::Link():pHead(NULL), iSize()
{
pHead = new Node;
pHead->next = NULL;
} Link::~Link()
{
Node * tmpNode = NULL;
Node * p = pHead->next;
while (p != NULL)
{
tmpNode = p->next;
delete p;
p = tmpNode;
}
delete tmpNode;
tmpNode = NULL; delete pHead;
p = NULL; iSize = ;
} /**********************************
链表选择排序(递增)
***********************************/
void Link::select_sort()
{
Node * p , *q;
int temp; for (p = pHead; p != NULL; p = p->next)
for (q = p->next; q != NULL; q = q->next)
{
if (p->data > q->data)
{
temp = p->data;
p->data = q->data;
q->data = temp;
}
}
} /**********************************
链表冒泡排序(递增)
***********************************/
void Link::bubble_sort()
{
Node *p;
int temp; /************************************************************************/
/* 冒泡排序是每次从头开始比较相邻的两个数,大小相反则交换,结束的 */
/* 条件是这一轮中没有发生交换,flag用来记录是否发生了交换 */
/************************************************************************/
int flag;
while (true)
{
flag = ;
for (p = pHead; p->next != NULL; p = p->next)
{
if (p->data > p->next->data)
{
temp = p->data;
p->data = p->next->data;
p->next->data = temp;
flag = ;
}
}
if (flag == )
break;
}
} /********************************
链表头部插入
*****************************/
void Link::insert_head(ElementType data)
{
Node * tmpNode = new Node;
tmpNode->data = data; tmpNode->next = pHead->next;
pHead->next = tmpNode; iSize++; tmpNode = NULL;
} /********************************
链表尾部插入
*****************************/
void Link::insert_tail(ElementType data)
{
Node * tmpNode = new Node;
tmpNode->data = data;
tmpNode->next = NULL; Node * p = NULL;
p = pHead;
while (p->next != NULL)
{
p = p->next;
} p->next = tmpNode;
iSize++; //delete tmpNode;
tmpNode = NULL;
//delete p;
p = NULL;
} /********************************
打印链表
*****************************/
void Link::display()
{
int count = ;
Node * tmpNode = NULL; tmpNode = pHead->next;
while (tmpNode != NULL)
{
std::cout<<tmpNode->data<<" ";
tmpNode = tmpNode->next; /********************************
* 输出格式控制,每行10个
**********************************/
if (count % == )
{
std::cout<<std::endl;
}
count++;
}
std::cout<<std::endl;
tmpNode = NULL;
} /********************************
查找结点
*****************************/
int Link::find(ElementType data)
{
int pos = ;
Node * tmpNode = NULL; tmpNode = pHead->next;
while (tmpNode != NULL)
{
if ( tmpNode->data == data)
{
return pos;
}
tmpNode = tmpNode->next;
pos++;
} tmpNode = NULL;
return -;
} /********************************
删除结点
*****************************/
bool Link::delete_node(int pos)
{
//序号超过链表范围则报错退出
if (pos > iSize -)
{
return false;
}
else
{
int k = ;
Node * tmpNode = NULL;
tmpNode = pHead;
while ( k < pos)
{
tmpNode = tmpNode->next;
k++;
}
Node * p = NULL;
p = tmpNode->next; tmpNode->next = tmpNode->next->next;
delete p;
p = NULL;
iSize--;
return true;
}
} /********************************
返回链表的长度
*****************************/
int Link::size()
{
return iSize;
} /********************************
链表的逆置
*****************************/
void Link::reverse()
{
Node * preNode = NULL;
Node * curNode = NULL;
Node * afterNode = NULL; if ( iSize == || iSize == )
{
return;
}
else if ( iSize >= )
{
preNode = pHead->next;
curNode = preNode->next;
afterNode = curNode->next; preNode->next = NULL; while (afterNode != NULL)
{
curNode->next = preNode; preNode = curNode;
curNode = afterNode; afterNode = afterNode->next;
} /********************************************************************
* 将当前结点的next置为前一个结点的过程是在每一次循环的开始,而最后一次
* 循环后无法进入下一次循环,需要补一次设置curNode的next的过程
*********************************************************************/
curNode->next = preNode; pHead->next = curNode;
}
preNode = NULL;
curNode = NULL;
afterNode = NULL;
} void Link::printhelp()
{
std::cout<<"*****************************************\n";
std::cout<<"当前链表为:"<<std::endl;
if (iSize == )
std::cout<<"NULL"<<std::endl;
else
display();
std::cout<<"输入你的选择:\n"
"0.从头部插入结点\n"
"1.从尾部插入结点\n"
"2.逆置链表\n"
"3.打印链表\n"
"4.删除结点\n"
"5.输出链表长度\n"
"6.查找结点\n"
"7.选择排序\n"
"8.冒泡排序\n"
"9.退出"<<std::endl;
std::cout<<"*****************************************\n";
}

main函数

// linklist.cpp : 定义控制台应用程序的入口点。
// #include "Link.h" int main(int argc, char * argv[])
{
Link myLink;
int pos;
char choice;
ElementType find_num = ;
int delchoice; for (int i = ; i < ; i ++)
{
myLink.insert_head(rand()%);
} myLink.printhelp();
std::cout<<"请选择:";
while ( std::cin>> choice)
{
switch(choice)
{
case '':
case '':
std::cout<<"\n暂无此功能!\n";
break;
case '':
myLink.reverse();
std::cout<<"\n逆置成功!\n";
break;
case '':
myLink.display();
std::cout<<"\n打印成功!\n";
break;
case '':
std::cout<<"\n输入要删除的节点序号:";
std::cin>>delchoice;
if (myLink.delete_node(delchoice) == true)
{
std::cout<<"\n删除成功!\n";
}
else
{
std::cout<<"\n删除失败!\n";
}
break;
case '':
std::cout<<"链表长为:"<<myLink.size()<<std::endl;
break;
case '':
goto exit;
break;
case '':
myLink.select_sort();
break;
case '':
myLink.bubble_sort();
break;
case '':
goto exit;
break;
default:
break;
}
myLink.printhelp();
std::cout<<"请选择:";
} exit:
system("pause");
return ;
}

运行:

C++单链表类(带头结点)的更多相关文章

  1. C/C++语言实现单链表(带头结点)

    彻底理解链表中为何使用二级指针或者一级指针的引用 数据结构之链表-链表实现及常用操作(C++篇) C语言实现单链表,主要功能为空链表创建,链表初始化(头插法),链表元素读取,按位置插入,(有序链表)按 ...

  2. C实现头插法和尾插法来构建单链表(带头结点)

    我在之前一篇博客<C实现头插法和尾插法来构建单链表(不带头结点)>中具体实现了怎样使用头插法和尾插法来建立一个不带头结点的单链表,可是在实际使用中.我们用的最多的还是带头结点的单链表.今天 ...

  3. 数据结构实验2:C++实现单链表类

    太简单了,直接贴题目然后上代码. 题目: 实验2 2.1 实验目的 熟练掌握线性表的链式存储结构. 熟练掌握单链表的有关算法设计. 根据具体问题的需要,设计出合理的表示数据的链式存储结构,并设计相关算 ...

  4. 数据结构-单链表-类定义2-C++

    上一次的C++链表实现两个单链表的连接不太理想,此次听了一些视频课,自己补了个尾插法,很好的实现了两个链表的连接,当然了,我也是刚接触,可能是C++的一些语法还不太清楚,不过硬是花了一些时间尽量在数据 ...

  5. 求单链表L各结点的阶乘之和(c语言)

    链表需要用到指针 阶乘需要用到递归 链表中的注意事项: 1.链表L是否等于NULL ----------是循环结束的条件 2.链表L->Data ---------取链表L中各个结点的值 3.L ...

  6. 数据结构-单链表-类定义C++

    原理可访问https://www.cnblogs.com/yang901112/p/11674333.html 头文件 #ifndef RLIST_H #define RLIST_H #include ...

  7. Intersection of Two Linked Lists (求两个单链表的相交结点)

    题目描述: Write a program to find the node at which the intersection of two singly linked lists begins. ...

  8. 单链表之C++实现

    在实现单链表时要注意对单链表的逻辑存储.物理存储有清晰的概念. 如上图链表已经完成,其逻辑结构如上.当需要对其进行操作,比如插入.删除,通常需要引 入指针,如上的ptr1.ptr2.在编程时一定要注意 ...

  9. 线性表源码分享(c++),包含顺序表、单链表、循环链表、双向链表

    ---恢复内容开始--- 我是一个c++和数据结构的初学者,本文主要是把清华大学出版社的数据结构(用面向对象方法与c++语言描述)(第2版)这本书中第二章线性表的源码抄下来,在学习的过程中有助于加深印 ...

随机推荐

  1. 外部连接mysql docker容器异常

    为了方便,使用python测试连接mysql容器 脚本内容非常简单 #!/usr/bin/python3 import pymysql conn=pymysql.connect(host=,passw ...

  2. MySQL 5.7新增加的json数据类型

    MySQL 5.7中有json存储类型了以前我们只能通过php来进行序列化了不过现在就不需要了我们可以直接使用MySQL 5.7的json数据类型来存储json格式数据了,具体来看介绍.   在MyS ...

  3. JS判断与过滤的表情符号表情的方法

    一.js判断文本中是否有表情符号表情 isEmojiCharacter(substring){ for ( var i = 0; i <substring.length; i ++){ var ...

  4. protected-broadcast 规范使用系统应用组件自定义广播

    1. protected-broadcast 规范使用系统应用组件自定义广播 参考:https://blog.csdn.net/TaylorPotter/article/details/7019424 ...

  5. 阶段5 3.微服务项目【学成在线】_day05 消息中间件RabbitMQ_5.RabbitMQ研究-入门程序-生产者

    1)java client 生产者和消费者都属于客户端,rabbitMQ的java客户端如下: 我们先用 rabbitMQ官方提供的java client测试,目的是对RabbitMQ的交互过程有个清 ...

  6. 【leetcode_easy】532. K-diff Pairs in an Array

    problem 532. K-diff Pairs in an Array 题意:统计有重复无序数组中差值为K的数对个数. solution1: 使用映射关系: 统计数组中每个数字的个数.我们可以建立 ...

  7. Java基础——接口和抽象类

    接口(interface) 什么是接口? 接口时抽象方法的合集.接口不可以被直接被实例化. 为什么要使用接口? 为了扩展.Java不支持多继承,但是通过接口就可以实现“多继承” 制定规则.接口就是规则 ...

  8. VSCode 怎么运行代码

    VSCode 怎么运行代码,集成终端和资源管理器也有互动.比如我们打开了一个脚本文件,希望直接执行这个脚本文件,就可以打开命令面板,运行 “在活动终端中运行活动文件”(Run Active File ...

  9. poj1222(高斯消元法解异或方程组+开关问题)

    题目链接:https://vjudge.net/problem/POJ-1222 题意:给定一个5×6的01矩阵,改变一个点的状态时它上下左右包括它自己的状态都会翻转,因为翻转2次等价与没有翻转,那么 ...

  10. kafka 名词解释(四)

    为什么要了解这些名词的解释呢?因为在学一个新的知识或者领域的时候,我们需要知道它所定义的概念和名词意思,因为只有这样我们才能理解和掌握这个新的知识点,才能更加系统的掌握这个技术. 一.名词解释 1.b ...