C++中的链表List♥---构想【2】
C++链表List结合类+界面选择
示例程序---留作日后参考调用】
----------------------------------------
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
typedef int DATA;
struct SNode{
DATA data;
SNode *pNext;
};
class CList{
private:
SNode *m_pHead;//成员变量日后尽量使用m_**格式;栈内的定义 系统自动定义和回收
char m_SName[20];
public:
CList(){//通过自构函数进行成员变量的初始化,便于私密性数据
//this->m_pHead = NULL;或者该语句,都行
m_pHead = NULL;//私有数据类内可以通过成员函数来实现改变
}
~CList(){//选择一 最后执行的析构,将系统申请的栈释放
cout << m_SName << endl;
RemoveALL();//此处该语句实现自动清除之前手动申请的堆空间
}
void Menu(){
cout << "1、插入链表数据: " << endl;
cout << "2、打印数据" << endl;
cout << "3、打印数据节点数量" << endl;
int i=0;//输入的数据势必是1 或 2 或 3
cout << "请选择需要操作的选项号码: ";
cin >> i;
switch (i){
case 1:
AddData();
break;
case 2:
Print(); system("pause");//在控制台黑白栏上的命令,即让显示的数据停顿一下
break;
case 3:
cout << "节点数据的个数: " << GetCount_ListNum() << endl; system("pause");
break;
}
}
void SetListName(const char *p){
strcpy(m_SName, p);
}
void AddHead(DATA data){
SNode *p = new SNode;
p->data = data;
p->pNext = m_pHead;
m_pHead = p;
}
void AddTail(DATA data){
if (m_pHead == NULL){
SNode *p = new SNode;
p->data = data;
m_pHead = p;
p->pNext = NULL;
}
else{
SNode *pT = new SNode;
SNode *p = m_pHead;
while (p->pNext != NULL){
p = p->pNext;
}
if (p->pNext == NULL){
pT->data = data;
pT->pNext = NULL;
p->pNext = pT;
}
}
}
void AddData(){
DATA data;
cout << "请输入一个整数数字: ";
cin >> data;
AddHead(data);
}
void Print(){
cout << this->m_SName << endl;//对象相关,先打印链表名字,后打印链表数据
SNode *p_run = m_pHead;
while (p_run){//p_run为真,即非空
cout << p_run->data << ' ';
p_run = p_run->pNext;
}
}
int GetCount_ListNum(){
SNode *p = m_pHead;
int i = 0;
while (p){
i++;
p = p->pNext;
}
return i;
}
void list_name(){
//cout << this->m_SName;或者该语句,都行
cout << m_SName;
}
void RemoveALL(){//选择二 程序结束,删除链表,即删除堆申请的空间。此法放在析构函数中更好
SNode *p = m_pHead, *p1;
while (p->pNext != NULL){
p1 = p; //如果直接使用p来删除p的话,就没地址实现p=p->pNext;
p = p->pNext;//此处只能使用一个中间变量来删除所有之前申请的堆地址!
delete p1;
}
}
};
int main(){
CList list1,list2;
int i=0,m=0,k=0;
do{
system("cls");//system();函数是调用命令提示符的函数 cls 是清屏的一个命令
cout << "请选择使用链表(List1 /List2)" << endl;
cin >> i;
switch (i){
case 1:
list1.Menu();
break;
case 2:
list2.Menu();
break;
}
} while (i);
return 0;
}
============================================================================================
C++中链表用C语言进行链表的书写】
/*C VS C++ 类比,看其区别*/
//1】this指针指向对象,然后对对象中的成员变量进行操作
//2】C++类中的成员变量;C中放在结构体外,即使定义函数并引用
//3】C++中申请和删除堆内存空间是:new /delete; C中申请和删除:(struct SNode *) malloc() / free
//4】C++结构体中:SNode *pNext; C中结构体:struct SNode *pNext;
//5】C++: void AddHead( DATA data)
// C : void AddHead(struct CList *const this, DATA data) //this指针传入地址,即在哪里; data即做什么
// 内部新申请的堆空间,因为需要添加新节点;其他成员函数直接定义结构体即可只是显示等操作
//6】C++: void Print()
// C : void Print(struct CList *const this)---传入地址 Menu(&list1);
//7】C++: CList(){}
// C : CList1(struct CList *const this){}---同上面类似
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<malloc.h>
#include<string.h>
typedef int DATA;
struct SNode{//新申请节点用的结构体
DATA data;
struct SNode *pNext;//此处C同C++有区别 缺省一个struct
};
struct CList{//头指针和其他变动用的结构体
struct SNode *m_pHead;//成员变量日后尽量使用m_**格式;栈内的定义 系统自动定义和回收
char m_SName[20];
};
void SetListName(struct CList *const this,const char *p){//struct SNode *this还理解为原定义的SNode
//地址空间
strcpy(this->m_SName, p);
}
void AddHead(struct CList *const this, DATA data){//struct SNode *this,是C相比C++最大的区别
//理解成为:在哪里,干什么/在哪里,添加什么数据
//C++直接将在哪里这一步包含隐藏在内了。
struct SNode *p = (struct SNode *)malloc(sizeof(struct SNode));
p->data = data;
p->pNext = this->m_pHead;
this->m_pHead = p;
}
void AddTail(struct CList *const this,DATA data){//指针指向的地址是定常量固定
if (this->m_pHead == NULL){
struct SNode *p = malloc(sizeof(struct SNode));
p->data = data;
this->m_pHead = p;
p->pNext = NULL;
}
else{
struct SNode *pT =(struct SNode *) malloc(sizeof(struct SNode));//(struct SNode *) 强制转换
struct SNode *p = this->m_pHead;
while (p->pNext != NULL){
p = p->pNext;
}
if (p->pNext == NULL){
pT->data = data;
pT->pNext = NULL;
p->pNext = pT;
}
}
}
void AddData(struct CList *const this){
DATA data;
printf( "请输入一个整数数字: ");
scanf_s("%d",&data);
AddHead(this,data);//成员函数之间的调用,也就是this指针的调用
}
void Print(struct CList *const this){
printf("%s\n",this->m_SName);//对象相关,先打印链表名字,后打印链表数据
struct SNode *p = this->m_pHead;
while (p){//p_run为真,即非空
printf("%d\n", p->data);
p = p->pNext;
}
}
int GetCount_ListNum(struct CList *const this){
struct SNode *p = this->m_pHead;
int i = 0;
while (p){
i++;
p = p->pNext;
}
return i;
}
void list_name(struct CList *const this){
//cout << this->m_SName;或者该语句,都行
printf("%s",this->m_SName);
}
void RemoveALL(struct CList *const this){//选择二 程序结束,删除链表,即删除堆申请的空间。此法放在析构函数中更好
struct SNode *p = this->m_pHead, *p1;
while (p){
p1 = p; //如果直接使用p来删除p的话,就没地址实现p=p->pNext;
p = p->pNext;//此处只能使用一个中间变量来删除所有之前申请的堆地址!
free (p1);
}
this->m_pHead = NULL;
}
void Menu(struct CList *const this){
printf("1、插入链表数据: \n");
printf("2、打印数据\n");
printf("3、打印数据节点数量\n");
int i = 0;
printf("请选择需要操作的选项号码: \n");
scanf_s("%d", &i);
switch (i){
case 1:
AddData(this);
break;
case 2:
Print(this); system("pause");//在控制台黑白栏上的命令,即让显示的数据停顿一下
break;
case 3:
printf("节点数据的个数: %d\n", GetCount_ListNum(this));
system("pause");
break;
}
}
CList1(struct CList *const this){
//构造函数
this->m_pHead = NULL;
SetListName(this, "List1: ");
}
CList2(struct CList *const this){
//构造函数
this->m_pHead = NULL;
SetListName(this, "List2:");
}
DeCList(struct CList *const this){
//析构函数
RemoveALL(this);
}
int main(){
struct CList list1 , list2 ;
CList1(&list1); CList2(&list2);
int i = 0, m = 0, k = 0;
DATA data=0;
do{
system("cls");//system();函数是调用命令提示符的函数 cls 是清屏的一个命令
printf("请选择使用链表(List1 /List2)\n");
scanf_s("%d",&i);
switch (i){
case 1:
Menu(&list1);//谁调用Menu,就调用谁的地址
break;
case 2:
Menu(&list2);
break;
}
} while (i);
DeCList(&list1);
DeCList(&list2);
return 0;
}

浙公网安备 33010602011771号