相信有了第二章顺序表的基础,小伙伴们学习第三章链表应该会轻松一点吧
目录
类模板下的单链表
1.1书上干净完整代码(无增改、适合自己动手实验)
1.2对书上代码的完善和对一些问题的验证和解释代码
1.补全一个函数:
2.this指针:
3.关于printlist函数的一点说明:(增改后代码第117行)
4.getlength函数最后一步为什么是--cnt(增改后代码第136行):
5.增改后代码:
6.增改后代码效果图:
7.增改后代码运行效果:
下面是书上单链表实现通信录的干净完整代码,基本一字不差~ 有需要的友友可以拿走~
#include
using namespace std;class phonebook
{
private:int ID;string name;string phone;string group;
public:phonebook() {};phonebook(int ID, string name, string phone, string group){this->ID = ID;this->name = name;this->phone = phone;this->group = group;}void print(){cout << this->ID << " " << this->name << " "<< this->phone << " " << this->group << endl;}bool operator==(phonebook& p){return (p.ID == this->ID) ? true : false;}
};template
struct node
{temp data;node* next;
};template
class linklist
{
private:node* front;
public:linklist(){this->front = new node;this->front->next = nullptr;}linklist(temp a[], int n);~linklist();void printlist();int getlengh() {};node* get(int i);int locate(temp x);void insert(int i, temp x);temp del(int i);
};//头插法
template
linklist::linklist(temp a[], int n)
{this->front = new node;this->front->next = NULL;for (int i = n - 1; i >= 0; i--){node* s = new node;s->data = a[i];s->next = this->front->next;this->front->next = s;}
}//尾插法
/*
template
linklist::linklist(temp a[], int n)
{this->front = new node;node* r = this->front();for (int i = 0; i < n; i++){node* s = new node;s->data = a[i];r->next = s;r = s;}r->next = NULL;
}
*/template
linklist::~linklist()
{node* p = this->front;while (p != NULL){this->front = p;p = p->next;delete front;}
}template
void linklist::printlist()
{node* p = this->front->next;while (p != NULL){p->data.print();//数据域中的print方法(需要用户自定义)p = p->next;}cout << endl;
}//按位置查找,返回地址
template
node* linklist::get(int i)
{node* p = this->front->next;int j = 1;while (p != NULL && j != i){p = p->next;j++;}return p;
}//按值查找,返回位置
template
int linklist::locate(temp x)
{node* p = this->front->next;int j = 1;while (p != NULL){if (p->data == x)return j;p = p->next;j++;}return -1;//如果没有找到,返回无效值
}template
void linklist::insert(int i, temp x)
{node* p = this->front;if (i != 1)p = get(i - 1);//get(i - 1)表示要插入的位置的前一个结点地址if (p != NULL){node* s = new node;s->data = x;s->next = p->next;p->next = s;}else{cout << "插入位置错误:" << endl;exit(0);}
}template
temp linklist::del(int i)
{node* p = this->front;if (i != 1)p = get(i - 1);node* q = p->next;p->next = q->next;temp x = q->data;delete q;return x;
}int main()
{phonebook pbook[4] ={{20181208,"mary","13011221827","classmates"},{20181127,"tom","13934621123","family"},{20181156,"john","1324579880","classmates"},{20181133,"lisa","1378001822","teacher"}};phonebook record(20181209, "phoenix", "1590209020", "teacher");linklistlist(pbook, 4);cout << "通信录内容列表:" << endl;list.printlist();list.insert(1, record);cout << "通信录内容列表:" << endl;list.printlist();phonebook x = list.del(3);cout << "删除元素:" << endl;x.print();cout << "通信录内容列表:" << endl;list.printlist();int p = list.locate(record);cout << "phoenix的位置是:" << p << endl;return 0;
}
代码效果图:
运行效果图:
(自己增改部分已经在代码中标明,有助于友友们对问题的理解)
书上没有对getlength函数做定义,本代码已经补全;
“this->”,是个指针,p用没有,就是本人觉得写着顺手,看代码的时候直接忽略即可~
为什么printlist函数是从this->front->next开始打印数据,而不是this->front呢?
因为无论在显示构造函数还是隐式构造函数中,都没有对头结点的数据域赋值。
如果我们将this->front->next改成this->front:程序不会报错,但是会在头结点数据域输出的位置输出一串乱码。这代表头结点的存储地址。
为了便于验证,我们在linklist中添加了getfront函数,用来输出头结点的数据域。
(见增改后代码第51行函数声明)验证结果已在运行框中显示。
其实有了说明3的解释,相信大家应该都能大概明白,这个顺序表的实际长度确实是cnt的,但是因为头结点默认不存放有效数据,所以考虑有效长度时不将其算在内。
#include
using namespace std;class phonebook
{
private:int ID;string name;string phone;string group;
public:phonebook() {};phonebook(int ID, string name, string phone, string group){this->ID = ID;this->name = name;this->phone = phone;this->group = group;}void print(){cout << this->ID << " " << this->name << " "<< this->phone << " " << this->group << endl;}bool operator==(phonebook& p){return (p.ID == this->ID) ? true : false;}
};template
struct node
{temp data;node* next;
};template
class linklist
{
private:node* front;
public:linklist(){this->front = new node;this->front->next = nullptr;}linklist(temp a[], int n);~linklist();temp getfront();//自己增加部分 书上无void printlist();int getlengh();node* get(int i);int locate(temp x);void insert(int i, temp x);temp del(int i);
};//头插法
template
linklist::linklist(temp a[], int n)
{this->front = new node;this->front->next = NULL;for (int i = n - 1; i >= 0; i--){node* s = new node;s->data = a[i];s->next = this->front->next;this->front->next = s;}
}//尾插法
/*
template
linklist::linklist(temp a[], int n)
{this->front = new node;node* r = this->front();for (int i = 0; i < n; i++){node* s = new node;s->data = a[i];r->next = s;r = s;}r->next = NULL;
}
*/template
linklist::~linklist()
{node* p = this->front;while (p != NULL){this->front = p;p = p->next;delete front;}
}//自己增加部分 书上无
template
temp linklist::getfront()
{node* p = front;temp x = p->data;return x;
}template
void linklist::printlist()
{node* p = this->front->next;//见说明3.while (p != NULL){p->data.print();//数据域中的print方法(需要用户自定义)p = p->next;}cout << endl;
}template
int linklist::getlengh()
{node* p = this->front;int cnt = 0;while (p != NULL){p = p->next;cnt++;}return --cnt;//见说明4
}//按位置查找,返回地址
template
node* linklist::get(int i)
{node* p = this->front->next;int j = 1;while (p != NULL && j != i){p = p->next;j++;}return p;
}//按值查找,返回位置
template
int linklist::locate(temp x)
{node* p = this->front->next;int j = 1;while (p != NULL){if (p->data == x)return j;p = p->next;j++;}return -1;//如果没有找到,返回无效值
}template
void linklist::insert(int i, temp x)
{node* p = this->front;if (i != 1)p = get(i - 1);//get(i - 1)表示要插入的位置的前一个结点地址if (p != NULL){node* s = new node;s->data = x;s->next = p->next;p->next = s;}else{cout << "插入位置错误:" << endl;exit(0);}
}template
temp linklist::del(int i)
{node* p = this->front;if (i != 1)p = get(i - 1);node* q = p->next;p->next = q->next;temp x = q->data;delete q;return x;
}int main()
{phonebook pbook[4] ={{20181208,"mary","13011221827","classmates"},{20181127,"tom","13934621123","family"},{20181156,"john","1324579880","classmates"},{20181133,"lisa","1378001822","teacher"}};phonebook record(20181209, "phoenix", "1590209020", "teacher");linklistlist(pbook, 4);cout << "通信录内容列表:" << endl;list.printlist();//自己增加部分 书上无cout << "验证头结点数据无效:" << endl;phonebook y = list.getfront();cout << "头结点数据为:" << endl;y.print();cout << endl;list.insert(1, record);cout << "通信录内容列表:" << endl;list.printlist();phonebook x = list.del(3);cout << "删除元素:" << endl;x.print();cout << "通信录内容列表:" << endl;list.printlist();int p = list.locate(record);cout << "phoenix的位置是:" << p << endl;//自己增加部分 书上无cout << "通信录的长度为:" << endl;cout << list.getlengh();return 0;
}
上一篇文章:数据结构与算法 第二章 顺序表 请参考以下链接 ~
https://blog.csdn.net/bc202205/article/details/129311232?spm=1001.2014.3001.5501
写码不易,关注一下作者再走呗o(╥﹏╥)o
谢谢支持~