資料結構自學筆記(未完成)
1、時間複雜度
2、空間複雜度
/* 問題: 在一個由自然數1-1000中某些數字所組成的陣列中,每個數字可能出現零次或者多次。 設計一個演算法,找出出現次數最多的數字。 */
#include
using namespace std;
void search(int a[], int len) // O(n) { int sp[1000] = {0}; int max = 0;
for(int i=0; i<len; i++) { sp[a[i] - 1]++; } for(int i=0; i<1000; i++) { if( max < sp[i] ) { max = sp[i]; } } for(int i=0; i<1000; i++) { if( max == sp[i] ) { cout << i + 1 << endl; } }
}
int main(int argc, char* argv[]) { int a[] = {1, 1, 3, 4, 5, 6, 6, 6, 3, 3};
search(a, sizeof(a)/sizeof(*a));
return 0;
} 3、泛型程式設計 // template // 函式模板可以自動推導具體型別,也可以指定具體型別 // 類模板只能指定具體型別 #include
using namespace std;
template // 函式模板 void Swap(T& a, T& b) { T t = a; a = b; b = t; }
template // 類模板 class Op { public: T process(T& v) { return v * v; } };
int main() { int a = 2; int b = 1;
Swap(a, b); // 不指定資料型別 cout << "a = " << a << " " << "b = " << b << endl; ///////////////////////////////////////////////////////////////////// double c = 0.01; double d = 0.02; Swap<double>(d, c); // 指定資料型別 cout << "c = " << c << " " << "d = " << d << endl; //////////////////////////////////////////////////////////////////////// Op<int> opInt; // 建立類物件 Op<double> opDouble; cout << "5 * 5 = " << opInt.process(5) << endl; cout << "0.3 * 0.3 = " << opDouble.process(0.3) << endl; return 0;
}
4、智慧指標 //
、頂層父類的設計
、線性表(List) // 線性表是具有相同型別的有n個數據元素的有限序列
、單鏈表
// 解決陣列大小不能動態擴充套件的問題 // 連結串列的記憶體要求比較靈活,不能用棧
#include #include
using namespace std;
//////////////////////StuInfo.cpp////////////////////////////// class StuInfo { public: int id; // 學號 string name; // 姓名
public: StuInfo(); ~StuInfo();
};
StuInfo::StuInfo() { name = “”; id = 0; }
StuInfo::~StuInfo() { }
///////////////////////LinkedList/////////////////////////// template struct Node { T info; // 資料 Node *next; // 指向下一個節 點的指標
Node<T>(){}
Node<T>(T x){ info = x; next = NULL; }
};
template class LinkedList //: public StuInfo { protected: // 只允許子類直接訪問 Node *header; int length;
public: LinkedList(); ~LinkedList(); void insert(int pos, T& info); void set(int id, T& info); void remove(int id); int find(int id); T getInfo(int id); int getLength(); void clear(); void print(); };
template LinkedList::LinkedList() { header = new Node(); // 建立頭節點 header->next = NULL; length = 0; }
template LinkedList::~LinkedList() { clear(); }
template void LinkedList::insert(int pos, T& info) { bool ret = (pos>=0) && (pos<=length);
if (ret)
{
Node<T> *current = header;
Node<T> *node = new Node<T>(info);
for (int index=0; index<pos; index++)
{
current = current->next;
}
node->next = current->next;
current->next = node;
length++;
}
else
{
cout << "positi is ERROR!" << endl;
}
return;
}
template void LinkedList::set(int id, T& info) //根據學生學號進行資訊修改 { int pos = find(id);
Node<T> *current = header;
for (int index=0; index<pos; index++)
{
current = current->next;
}
current->next->info = info;
return;
}
template void LinkedList::remove(int id) //根據學生學號進行刪除 { int pos = find(id);
Node<T> *current = header;
for (int index=0; index<pos; index++) // 刪除的是pos節點的下一個節點
{
current = current->next;
}
Node<T> *toDel = current->next;
current->next = toDel->next;
delete toDel;
length--;
return;
}
template int LinkedList::find(int id) //根據學號進行查詢,返回節點位置 { Node *current = header;
for (int index=0; index<=length; index++)
{
if ( (current->next != NULL) && (current->next->info.id == id) )
{
return index;
}
current = current->next;
}
return -1;
}
template T LinkedList::getInfo(int id) { int pos = find(id);
Node<T> *current = header;
for (int index=0; index<pos; index++)
{
current = current->next;
}
T info = current->next->info;
return info;
}
template int LinkedList::getLength() //獲得連結串列長度 { return length; }
template void LinkedList::clear() // 清空節點 (不需要移動節點,挨個刪除就可以) { for (int index = 0; index < length; index++) { Node *toDel = header->next; header->next = toDel->next;
delete toDel;
}
length =0;
return;
}
template void LinkedList::print() //列印連結串列資訊 { Node *current = header;
for (int index=0; index<length; index++)
{
cout << current->next->info.id << "," << current->next->info.name << endl;
current = current->next;
}
cout << endl;
return;
}
Lists.insert(0, info1);
Lists.print();
Lists.insert(1, info2);
Lists.print();
Lists.insert(2, info3);
Lists.print();
Lists.insert(3, info4);
Lists.print();
Lists.insert(4, info5);
Lists.print();
cout << “連結串列長度為:” << Lists.getLength() << endl;
cout << Lists.getInfo(1001).id << "," <<Lists.getInfo(1001).name << endl;
cout << endl;
Lists.set(1003, info5);
Lists.print();
cout << "連結串列長度為:" << Lists.getLength() << endl;
Lists.remove(1002);
Lists.print();
cout << "連結串列長度為:" << Lists.getLength() << endl;
Lists.clear();
Lists.print();
return 0;
}
、連結串列反轉
#include #include
using namespace std;
//////////////////////StuInfo.cpp////////////////////////////// class StuInfo { public: int id; // 學號 string name; // 姓名
public: StuInfo(); ~StuInfo();
};
StuInfo::StuInfo() { name = “”; id = 0; }
StuInfo::~StuInfo() { }
///////////////////////LinkedList/////////////////////////// template struct Node { T info; // 資料 Node *next; // 指向下一個節 點的指標
Node<T>(){next = NULL;}
Node<T>(T x){ info = x; next = NULL; }
};
template class LinkedList //: public StuInfo { public: // 只允許子類直接訪問 Node *header; int length;
public: LinkedList(); ~LinkedList(); void insert(int pos, T& info); void set(int id, T& info); void remove(int id); int find(int id); T getInfo(int id); int getLength(); Node* reverseList(Node* node); void clear(); void print(Node* node); };
template LinkedList::LinkedList() { header = new Node(); // 建立頭節點 header->next = NULL; length = 0; }
template LinkedList::~LinkedList() { clear(); }
template void LinkedList::insert(int pos, T& info) { bool ret = (pos>=0) && (pos<=length);
if (ret)
{
Node<T> *current = header;
Node<T> *node = new Node<T>(info);
for (int index=0; index<pos; index++)
{
current = current->next;
}
node->next = current->next;
current->next = node;
length++;
}
else
{
cout << "positi is ERROR!" << endl;
}
return;
}
template void LinkedList::set(int id, T& info) //根據學生學號進行資訊修改 { int pos = find(id);
Node<T> *current = header;
for (int index=0; index<pos; index++)
{
current = current->next;
}
current->next->info = info;
return;
}
template void LinkedList::remove(int id) //根據學生學號進行刪除 { int pos = find(id);
Node<T> *current = header;
for (int index=0; index<pos; index++) // 刪除的是pos節點的下一個節點
{
current = current->next;
}
Node<T> *toDel = current->next;
current->next = toDel->next;
delete toDel;
length--;
return;
}
template int LinkedList::find(int id) //根據學號進行查詢,返回節點位置 { Node *current = header;
for (int index=0; index<=length; index++)
{
if ( (current->next != NULL) && (current->next->info.id == id) )
{
return index;
}
current = current->next;
}
return -1;
}
template T LinkedList::getInfo(int id) { int pos = find(id);
Node<T> *current = header;
for (int index=0; index<pos; index++)
{
current = current->next;
}
T info = current->next->info;
return info;
}
template int LinkedList::getLength() //獲得連結串列長度 { return length; }
template Node* reverseList(Node* head) // 反轉連結串列 { Node* prev = head; Node* current = prev->next; Node* next = NULL;
while (current != NULL) // 兩個節點
{
next = current->next;
if (current == head->next) // 第一個節點插入時 尾部連線
current->next = NULL;
else // 後來的節點插入時 尾部連線
current->next = prev->next;
prev->next = current; // 頭部連線
current = next; // 移位
}
return head;
}
template void LinkedList::clear() // 清空節點 (不需要移動節點,挨個刪除就可以) { for (int index = 0; index < length; index++) { Node *toDel = header->next; header->next = toDel->next;
delete toDel;
}
length =0;
return;
}
template void LinkedList::print(Node* node) //列印連結串列資訊 { Node *current = node;
while(current->next != NULL)
{
cout << current->next->info.id << "," << current->next->info.name << endl;
current = current->next;
}
cout << endl;
return;
}
Lists.insert(0, info1);
Lists.insert(1, info2);
Lists.insert(2, info3);
Lists.insert(3, info4);
Lists.insert(4, info5);
Lists.print(Lists.header);
Node<StuInfo>* p = NULL;
p = reverseList(Lists.header);
Lists.print(p);
/*
cout << "連結串列長度為:" << Lists.getLength() << endl;
cout << Lists.getInfo(1001).id << "," <<Lists.getInfo(1001).name << endl;
cout << endl;
Lists.set(1003, info5);
Lists.print(Lists.header);
cout << "連結串列長度為:" << Lists.getLength() << endl;
Lists.remove(1002);
Lists.print(Lists.header);
cout << "連結串列長度為:" << Lists.getLength() << endl;
Lists.clear();
Lists.print(Lists.header);
*/
return 0;
}
、靜態單鏈表 // 單鏈表中頻繁增加和刪除資料元素會產生記憶體碎片 // 順序表 + 單鏈表 = 靜態單鏈表
、雙向連結串列
#include #include
using namespace std;
/////////////////Info/////////////////// class StuInfo { public: string name ; int ID;
StuInfo();
~StuInfo();
};
StuInfo::StuInfo() { name = “”; ID = 0; };
StuInfo::~StuInfo() {
};
////////////////DuaLinkList//////////////////// template class Node { public: T info; Node* next; Node* prev;
public: Node() { next = NULL; }
Node<T>(T& info)
{
this->info = info;
next = NULL;
prev = NULL;
}
};
template class DuaLinkList : public Node { public: Node* head; int m_length;
public: DuaLinkList(); ~DuaLinkList();
bool insert(int pos, T& info);
bool remove(int pos);
void print(Node<T>* current);
void clear();
};
template DuaLinkList::DuaLinkList() { head = new Node(); head->next = NULL; m_length = 0; }
template DuaLinkList::~DuaLinkList() { clear(); }
template bool DuaLinkList::insert(int pos, T& info) { int ret = (pos>=0) && (pos<=m_length);
if (ret)
{
Node<T>* current = head;
Node<T>* node = new Node<T>(info);
for (int i=0; i<pos; i++)
{
current = current->next;
}
node->next = current->next; // 1
current->next = node; // 2
if (current->next != NULL)
current->next->prev = node; // 3 不是尾節點
if (current != head) // 4 不是頭節點
node->prev = current;
else
node->prev = NULL; // 4 是頭節點
m_length++;
return true;
}
else
{
cout << "insert error" << endl;
return false;
}
}
template bool DuaLinkList::remove(int pos) { int ret = (pos>=0) && (pos<=m_length);
if (ret)
{
Node<T> *current = head;
for (int index=0; index<pos; index++) // 刪除的是pos節點的下一個節點
{
current = current->next;
}
Node<T>* toDel = current->next;
current->next = toDel->next;
if (toDel->next != NULL)
toDel->next->prev = current;
delete toDel;
m_length--;
}
return true;
}
template void DuaLinkList::print(Node* current) { current = head;
while (current != NULL)
{
cout << current->info.ID << "::" << current->info.name << endl;
current = current->next;
}
}
template void DuaLinkList::clear() {
}
int main() { DuaLinkList list; StuInfo stu1, stu2, stu3;
stu1.ID = 101;
stu1.name = "aaa";
stu2.ID = 102;
stu2.name = "bbb";
stu3.ID = 103;
stu3.name = "ccc";
list.insert(0, stu1);
list.insert(1, stu2);
list.insert(2, stu3);
list.insert(3, stu2);
list.remove(2);
list.print(list.head);
}