#include<iostream>
#include<string>
#include<memory>
#include<stdexcept>
using namespace std;
template<typename T>
class LinkedList{
typedef struct Node {
T data;
shared_ptr<Node> next;
Node() :data(T{}),next(nullptr) {} //default //? //data不初始化是有问题的
Node(T e, shared_ptr<Node> link = nullptr) :data(e),next(link){} //why written like this//类型传成sharedptr会不会直接stop?//所以我直接写在一起//Node只是结构体,不是模板,不能写成Node<T>
};//
private: //what***?
shared_ptr<Node>head; //typedef struct Node { } Node; 定义的是普通结构体 Node,不是 Node<T
shared_ptr<Node>tail;
int length; //i-dle的歌好听!
public:
LinkedList() :length(0),tail(nullptr),head(nullptr){
}//用来初始化head
//shared_ptr 默认构造是 nullptr,但是我的带参数构造函数假设 head 已可用。//?
LinkedList(const T v[],int n ) :length(0),tail(nullptr),head(nullptr){
for (int i = 0; i < n; i++) {
insert_at_tail(v[i]);
}
}//第一要复用函数,第二head是nullptr
virtual ~LinkedList() {} //为什么书上写的是virtual ~ ?//对啊吃什么?//virtual是通常用于一个场景是吧
int GetLength() const {
int x; auto it = head;
for (x = 0;it!=nullptr; x++) {
//head = head->next;//const 函数里不能修改head而且本来也不能
it = it->next;
}
return x;
}
void set_tail() {
if (!head) { tail = nullptr; return; }
auto temp = head;
while (temp->next) temp = temp->next;
tail = temp;
}
bool isEmpty() {
if (!head) return 1;
return 0;
}
void Clear() {
head = nullptr;
tail = nullptr;
length = 0;
}
void insert_at_head(const T&e) {
//if (!head) { auto it2 = make_shared<Node>(e, nullptr); head = it2; }//内存泄露
head = make_shared<Node>(e,head);
if (!tail)tail = head;//set_tail(); //效率低下
length++;
}
void insert_at_tail(const T& e) {
auto it =make_shared<Node>(e, nullptr);
if (!head) { //head = it=tail;//关于赋值数据顺序
head = tail = it;
}
//set_tail();//效率低下
else {
tail->next = it; //不能让tail为空
tail = it;
}
length++;
}
int find_position_return(const T& e) {
auto it = head; int k = 1;
while (it) { //检查眼前就是检查所有
if (it->data == e) return k;
it = it->next; k++;
}
return -1;
}
void remove_with_pos(int pos) {
if (pos<1 || pos>length) throw out_of_range("The position is error.");
if (pos == 1) {
head = head->next; if (!head)tail = nullptr;
}
else {
auto it = head;
for (int i = 1; i < pos-1; i++) {
it = it->next;
}
auto it2 = it->next;
it->next = it2->next;
if (pos == length)tail = it;
}
length--;
}
void show() {
auto it = head;
while (it) {
cout << it->data << " ";
it = it->next;
}
cout << endl;
}
};
int main() {
int a[5] = { 1,2,3,4,5 };
LinkedList<int> list(a,5);//LinkedList 是模板类,你需要指定类型参数//fixed?
cout << "Length: " << list.GetLength() << endl; // 应该输出 5
list.show(); // 应该输出 1 2 3 4 5
cout << endl;
list.insert_at_head(0);
list.show(); // 应该输出 0 1 2 3 4 5
list.remove_with_pos(2);
cout << "After removing position of 2,the list shows:" << endl;
list.show();
cout<<"The position of 3 is "<<list.find_position_return(3)<<endl;
return 0;
}
确实看得出来上课确实什么都没讲,我缺乏的点在于构造的参数关系,以及内存空间的权限,以及正反逻辑,而且还有暂时对算法时间复杂度忽略的问题
当然作业还有SeqList,现在我打算做这个作业。
SeqList(const SeqList&) = delete;
SeqList& operator=(const SeqList&) = delete;
这是禁用拷贝操作,暂时没看懂。
#include<iostream>
#include<memory>
#include<string>
#include<stdexcept>
using namespace std;
template<typename T>
class SeqList {
private:
int maxSize;
int length;
T* data;
public:
SeqList() :data(), length(0), maxSize(0) {}
SeqList(const T v[], int n) :length(0),maxSize(0),data(nullptr){
for (int i = 0; i < n; i++)
push_back(v[i]);
}//error
virtual ~SeqList() { delete[] data; }//unknown before
int getLength() { return length; }
//void expand() { if (length >= maxSize)maxSize = (maxSize==0)?1:2*maxSize; auto it = new T[maxSize]; for (int i = 0; i < length; i++) { it[i] = data[i]; }auto temp = data; data = it; delete[] temp; return; }//error//写法很危险------maxSize 在申请内存前就改了。如果 new 抛出异常,maxSize 已经是新值但内存没申请成功,对象处于不一致状态。
void expand() {
if (length >= maxSize)newSize = (maxSize == 0) ? 1 : 2 * maxSize; auto it = new T[newSize];
for (int i = 0; i < length; i++) {
it[i] = data[i];
}
delete[] data; data = it; maxSize = newSize; return;
}
void push_front(const T&e) {
expand();
for (int i = length; i > 0; i--) {
data[i] = data[i-1];
}
length++;
data[0] = e;
}
void push_back(const T& e) {
expand();
data[length] = e;//error
length++;
}
int find_return_index(const T& e) {
for (int i = 0; i < length; i++) {
if (data[i] == e) return i;
}
return -1;
}
void remove(int pos) {
if (pos<1 || pos>length) throw out_of_range("The position is out of range.");
for (int i = pos-1; i <length-1 ; i++) {
data[i] = data[i + 1];
}
length--;
}
void show() {
for (int i = 0; i < length;i++)cout << data[i] << " ";
cout << endl;
}
};
int main() {
int a[5] = { 2,3,4,5,6 };
SeqList<int> list(a, 5);
cout << "Length: " << list.getLength() << endl;
list.show();
cout << endl;
list.push_front(0);
cout << "Length: " << list.getLength() << endl;
list.show();
list.remove(2);
cout << "After removing position of 2,the list shows:" << endl;
list.show();
cout << "The position of 5 is " << list.find_return_index(5) << endl;
return 0;
}