using namespace std;//类class List{
public:
//构造器初始化,⽣成头节点 List() {
head = new Node; head->next = NULL; }
//成员函数
void createList();
void insertList(int data); void travelList(int chance); void input(); int addNode();
void deleteData(int addNum); void ifClear(); void clearList(); //重载下标
int operator[](int idx); //重载+
friend List operator+(List& List_1, List& List_2); //重载- friend List operator-(List& List_1, List& List_2); //重载<<
friend ostream& operator<<(ostream& os, List& list); //重载>>
friend istream& operator>>(istream& is, List& list); //冒泡排序
void bubbleSortList(List& list);private: //数据成员 struct Node {
int data; //数据域
struct Node* next; //指针域 } *head;//头指针 int num;//链表元素个数};
//头插法⽣成节点
void List::insertList(int data){
Node* cur = new Node; //插⼊数据
cur->data = data; //插⼊节点
cur->next = head->next; head->next = cur;}
//调⽤insertList输⼊数据,⽣成链表void List::input(){
cout << \"请输⼊链表数量长度:\"; cin >> num;
srand(time(NULL));
for (int i = 0; i < num; i++) {
insertList(rand() % 100); }}
//任意位置插⼊节点int List::addNode()
{
int d, idx;
cout << \"请输⼊你要插⼊的节点数据:\"; cin >> d;
cout << \"请输⼊你要插⼊的节点位置: \"; cin >> idx; Node* tp = NULL; Node* link = head;
//寻找插⼊位置
if (idx<1 || idx>num + 1) {
cout << \"操作⾮法\" << endl; return num; } else {
for (int i = 0; i < idx; i++) {
tp = link;
link = link->next; }
Node* cur = new Node; tp->next = cur; cur->data = d; cur->next = link; travelList(1); return ++num; }}
ofstream mycout1(\"D:/text1.txt\");ofstream mycout2(\"D:/text2.txt\");//遍历链表并将数据存⼊⽂件void List::travelList(int chance){
Node* temp = head->next; //防⽌头指针地址改变 while (temp != NULL) {
cout << temp->data << \" \"; if (chance == 1)
mycout1 << temp->data << \" \"; else
mycout2 << temp->data << \" \"; temp = temp->next; }
cout << endl;}
//删除节点
void List::deleteData(int addNum){
int i, j = 0;
cout << \"请问您要删除第⼏个数据: \"; cin >> i;
Node* tp = NULL;
Node* link = head;//link为删除节点后⾯的⼀个节点,temp为删除节点 if (addNum < i || i < 0)
cout << \"操作⾮法!!\" << endl; else {
while (link->next) {
tp = link->next; //第⼀个节点 j++;
if (i == j) //找的删除的节点 {
link->next = tp->next; delete tp; break; }
link = link->next; }
travelList(1); }}
//清空链表
void List::clearList()
{
Node* tp = NULL;
Node* ph = head->next; while (head->next) {
tp = ph;
ph = ph->next; delete tp;
head->next = ph; }
travelList(1); cout << endl;}
//询问是否清空void List::ifClear(){
string i;
if (!head->next) {
cout << \"链表已清空\" << endl; }
else {
cout << \"是否清空链表(是/否):\"; cin >> i;
if (i == \"是\") {
clearList();
cout << \"链表清空完成\" << endl; } else
cout << \"链表未清空\" << endl; }}
//冒泡排序
void List::bubbleSortList(List& list){
//求list链表长度len int len=0;
//临时指针phead
Node* phead = list.head->next; while (phead) {
len++;
phead = phead->next; }
//冒泡排序
for (int i=0;i//phead指向头结点 phead = list.head; //ph1指向⾸元结点Node* ph1 = phead->next; //ph2指向⾸元结点的后继 Node* ph2 = ph1->next; //进⼊循环冒出最⼤的数
for (int j = 0; j < len - 1 - i; j++) {
//如果前⾯的值⼤于后⾯的值则交换 if (ph1->data > ph2->data) {
phead->next = ph2; ph1->next = ph2->next; ph2->next = ph1;
//结点交换后,ph1与ph2位置颠倒回来 Node* temp = ph1; ph1 = ph2; ph2 = temp; }
//如果不需要交换,三指针移动 phead = phead->next; ph1 = ph1->next; ph2 = ph2->next; }
}
//打印结点数据
phead = list.head->next; while (phead) {
cout << phead->data << \" \"; phead = phead->next; }
cout << endl;}
//下标重载
int List::operator[](int idx){
//临时指针temp,为了防⽌头指针改变 Node* temp = head;
//如果下标⼩于链表长度进⾏取值 if (idx < num) {
for (int i = 0; i < idx; i++) {
temp = temp->next; } }
return temp->data;}
//+ 重载
List operator +(List & List_1, List & List_2){
//由链表1⽣成链表3 List List_3;
//⽣成临时指针temp_1
List::Node* temp_1 = List_1.head->next; //把链表1的值给链表3 while (temp_1) {
List_3.insertList(temp_1->data); temp_1 = temp_1->next; }
//⽣成临时指针temp_2
List::Node* temp_2 = List_2.head->next; //把链表2的值给链表3 while (temp_2) {
List_3.insertList(temp_2->data); temp_2 = temp_2->next; }
return List_3;}
//- 重载
List operator -(List & List_1, List & List_2){
//⽣成链表4 List List_4;
//⽣成临时指针temp_1,temp_2
List::Node* temp_1 = List_1.head->next; List::Node* temp_2 = List_2.head->next; //flag为1链表2有链表1的值,为0则没有 int flag = 0;
//⽐较链表⼀和链表⼆,不等就将数据存⼊List_4 while (temp_1) {
//临时指针temp_2回溯
temp_2 = List_2.head->next; while (temp_2) {
//判断是否有相同值
if (temp_1->data == temp_2->data) {
flag = 1; break; }
//指针移动
temp_2 = temp_2->next; }
//没有相同值List_4则插⼊数据 if (!flag) {
List_4.insertList(temp_1->data);
}
//指针移动,开始下⼀轮对⽐ temp_1 = temp_1->next; flag = 0; }
return List_4;}
//重载<<
ostream& operator<<(ostream & os, List & list){
list.bubbleSortList(list); return os;}
//重载>>
istream &operator>>(istream & is, List & list){
int size, i=0;
cout << \"(输⼊链表长度):\"; is >> size;
//当iint data; is >> data; //插⼊数据list.insertList(data); i++; }
return is;}
int main(){
//初始化,⽣成List_1 List List_1; //输⼊链表长度 List_1.input();
//遍历链表,并存⼊text1⽂件 List_1.travelList(1);
//添加节点并返回总结点数
int addNum = List_1.addNode(); //删除节点
List_1.deleteData(addNum);
//初始化,⽣成List_2 List List_2; //输⼊链表长度 List_2.input();
//遍历链表,并存⼊text2⽂件 List_2.travelList(2);
//重载下标
cout << \"取链表2的第⼆个元素:\"; cout << List_2[2]<List_3 = List_1 + List_2; cout << \"两链表+为:\";List_3.bubbleSortList(List_3); //重载- List List_4;
List_4 = List_1 - List_2; cout << \"两链表-为:\";
List_4.bubbleSortList(List_4); //重载<<
cout << \"cout<> List List_5;cout << \"cin>>List_5\"; cin >> List_5;
cout << \"链表List_5: \" << List_5; //询问是否清空链表1 List_1.ifClear(); //关闭打开的⽂件 mycout1.close(); mycout2.close(); return 0;}
⽤类创建单链表时,可以将结构体封装为私有成员,在构造函数中初始化链表极为⽅便;链表的删除操作需要先进⾏遍历,并且遍历途中不能随意改变头结点的位置,所以在进⾏链表的操作时,皆需要临时变量防⽌头指针改变;除此之外,在进⾏冒泡排序时,需要画图理清逻辑,虽然⽐较过后,链表的连接⽅式改变了,但是ph1与ph2位置颠倒,需要互换回来,使下⼀次⽐较正常运⾏;运算符“+”号重载时,如果直接由链表1⽣成链表3,在进⾏减操作时,会发现链表1随链表3的改变⽽改变了,导致在进⾏“-”操作时出错,后在“+”操作时,对链表3进⾏逐⼀赋值,问题得到解决。总的来说,此次试验对友元函数和运算符重载有了新的收获,例如如果将”<<”重载,”<<”会根据你输出的内容来调⽤相应的函数,从⽽在使⽤cout时更为⽅便。