1. 程式人生 > >資料結構自學筆記(未完成)

資料結構自學筆記(未完成)

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);

}