目录
实验目的及要求
1.掌握线性表的概念。
2.掌握线性表的链式存储和基本操作运算。
3.掌握链表的基本操作运算。
4.加深对链式存储实际结构的理解,逐步培养解决实际问题的编程能力。
实验原理
链表的基本操作运算和综合运用
实验环境
Visual studio 2019
实验方案设计
设计一算法,实现两个非递减的线性表的合并,采用链式存储结构,能够输出合并前和合并后链表的内容。
实验过程
1.利用头文件和参考代码,规划进行一定的修改,满足设计的需求。
2.线性表的合并并不需要删除这一操作,所以删除这一部分的代码,因为涉及到合并,所以加入拷贝构造函数和运算符重载。
3.主函数加入一些语句,提高交互性。
结论(代码)
LinList.h
#ifndef _LINLIST_H
#define _LINLIST_H
#include <iostream>
using namespace std;
template<class T> class LinList;
template<class T> class ListNode {
friend class LinList<T>;
private:
ListNode<T>* next;
T data;
public:
ListNode(ListNode<T>* ptrNext = NULL) {
next = ptrNext;
}
ListNode(const T& item, ListNode<T>* ptrNext = NULL) {
data = item;
next = ptrNext;
}
~ListNode(void) {
}
};
template<class T> class LinList {
private:
ListNode<T>* head;
int size;
public:
ListNode<T>* Index(int i);
LinList(void);
LinList(LinList<T>& s);
~LinList(void);
int Size(void) const;
void Insert(const T& item, int i);
T GetData(int i);
LinList<T>& operator=(const LinList <T>& s)
{
head = new ListNode<T>();
ListNode<T>* p, * q;
p = s.head->next;
q = head;
while (p)
{
ListNode<T>* newnode = new ListNode<T>(p->data, q->next);
p = p->next;
q->next = newnode;
q = newnode;
}
size = s.size;
return *this;
};
void OrderInsert(T x);
};
template<class T> LinList<T>::LinList() {
head = new ListNode<T>();
size = 0;
}
template<class T>LinList<T>::LinList(LinList <T> & s)
{
head = new ListNode<T>();
ListNode<T>* p, * q;
p = s.head->next;
q = head;
while (p)
{
ListNode<T>* newnode = new ListNode<T>(p->data, q->next);
p = p->next;
q->next = newnode;
q = newnode;
}
size = s.size;
};
template<class T> LinList<T>::~LinList() {
ListNode<T>* p, * q;
p = head;
while (p != NULL) {
q = p;
p = p->next;
delete q;
}
size = 0;
head = NULL;
}
template<class T> int LinList<T>::Size() const {
return size;
}
template<class T> ListNode<T>* LinList<T>::Index(int i) {
if(i<-1 || i>size - 1) {
cout << "The index is invalid!" << endl;
exit(0);
}
if (i == -1) return head;
ListNode<T>* p = head->next;
int j = 0;
while (p != NULL && j < i) {
p = p->next;
j++;
}
return p;
}
template<class T> void LinList<T>::Insert(const T& item, int i) {
if (i<-1 || i>size) {
cout << "The index is invalid!" << endl;
exit(0);
}
ListNode<T>* p = Index(i - 1);
ListNode<T>* q = new ListNode<T>(item, p->next);
p->next = q;
size++;
}
template<class T> T LinList<T>::GetData(int i) {
if (i<0 || i>size - 1) {
cout << "The index is invalid!" << endl;
exit(0);
}
ListNode<T>* p = Index(i);
return p->data;
}
template<class T> void LinList<T>::OrderInsert(T x) {
ListNode<T>* curr, * pre;
curr = head->next;
pre = head;
while (curr != NULL && curr->data <= x) {
pre = curr;
curr = curr->next;
}
ListNode<T>* q = new ListNode<T>(x, pre->next);
pre->next = q;
size++;
}
#endif
Main.cpp
#include<iostream>
#include"LinList.h"
#include<stdlib.h>
using namespace std;
template<class T>
void Merge(LinList<T> LA, LinList<T> LB, LinList<T>& LC)
{
T x;
LC = LA;
for (int j = 0; j < LB.Size(); j++)
{
x = LB.GetData(j);
LC.OrderInsert(x);
}
}
int main()
{
LinList<int> mylistA, mylistB, mylistC;
int x;
int temp;
cout << "创建单链表A" << endl;
cout << "请输入:(输入零停止)";
cin >> x;
while (x != 0)
{
mylistA.OrderInsert(x);
cout << "请输入:(输入零停止)";
cin >> x;
}
cout << "创建单链表B" << endl;
cout << "请输入:(输入零停止)";
cin >> x;
while (x != 0)
{
mylistB.OrderInsert(x);
cout << "请输入:(输入零停止)";
cin >> x;
}
cout << "单链表A:";
for (int i = 0; i < mylistA.Size(); i++)
cout << mylistA.GetData(i) << " ";
cout << "单链表B:";
for (int i = 0; i < mylistB.Size(); i++)
cout << mylistB.GetData(i) << " ";
Merge<int>(mylistA, mylistB, mylistC);
cout << "合并后的单链表C:";
for (int i = 0; i < mylistC.Size(); i++)
cout << mylistC.GetData(i) << " ";
system("pause");
return 0;
}
小结
节点类和链表类的封装,为了访问节点类的私有成员变量,须定义友元链表类。