本科沒有學習過數據結構,之前也只是泛泛的看看鏈表的原理,並沒有實際編寫,昨天就係統的將鏈表的各項功能給實現了下,其中包括:移除,插入,更改,清空,打印,鏈表反轉等功能;其中,鏈表的反轉這在《劍指offer》以及其他面試中經常會被問到的問題;同時,對鏈表的熟悉可以爲後期的隊列以及棧等的編寫提供基礎,所以還是很有必要從頭將鏈表進行弄明白。
- 首先建立List.h文件,爲了和STL中的list進行區分,所以才用大寫表示:
#ifndef _LIST_H_
#define _LIST_H_
#include<iostream>
#include<string>
using namespace std;
struct Info
{
string name;
int id;
};
struct Node
{
Info val;
Node * next;
Node(Info x):val(x),next(NULL){};
};
class List
{
public:
List();
~List();
void ListHead(Info val); //插入鏈表頭
void Insert(Info val,int pos); //在pos位置插入信息val
void Insert(Info val);//默認在鏈表的最後添加數據
int Find(Info val);//查找val,並返回val前一個節點的指針
void Remove(Info val);//移除val
void Update(Info val,Info val1);//更新val的值爲val1
void Print();//打印鏈表
void erase();//清空鏈表
void Reverse();//鏈表反轉
private:
Node * head;//一個鏈表的頭指針
int length;//鏈表的長度
};
#endif
2、然後建立List.cpp文件
#include"List.h"
List::List()
{
head = NULL;
length = 0;
}
List::~List()
{
Node * temp = head;
for(int i = 0;i < length;i++)
{
delete temp;
temp = temp->next;
}
}
//創建一個鏈表頭
void List::ListHead(Info val)
{
Insert(val,0);
}
//在鏈表中pos的位置插入數據
void List::Insert(Info val,int pos)
{
if(pos < 0)
cout<<"Error:pos must be integer!";
Node *temp = head;
Node *node = new Node(val);
int index = 1;
if(pos == 0)
{
node->next = temp;
head = node;
length++;
return;
}
while(temp!=NULL && index < pos)
{
temp = temp->next;
index++;
}
if(temp == NULL)
{
cout<<"Error:Insert failed!"<<endl;
return;
}
node->next = temp->next;
temp->next = node;
length++;
}
//默認在鏈表的末尾添加數據
void List::Insert(Info val)
{
Node *temp = head;
Node *p;
Node* node = new Node(val);
while(temp->next!=NULL)
{
temp = temp->next;
}
node->next = temp->next;
temp->next = node;
length++;
}
//在鏈表中查找val
int List::Find(Info val)
{
Node* temp = head;
int index = 1;
for(;temp;temp = temp->next)
{
if(temp->val.id == val.id && temp->val.name == val.name)
return index;
index++;
}
return -1;
}
//刪除val值
void List::Remove(Info val)
{
int pos = Find(val);
if(pos == -1)
cout<<"Error:Remove failed!"<<endl;
if(pos == 1)
{
head = head->next;
length--;
return;
}
int index = 2;
Node* temp = head;
while(index<pos)
{
temp = temp->next;
index++;
}
temp->next = temp->next->next;
length--;
}
//打印鏈表
void List::Print()
{
Node* temp = head;
if(temp == NULL)
{
cout<<"Error:print failed!"<<endl;
return;
}
while(temp!=NULL)
{
cout<<temp->val.name<<"<***>"<<temp->val.id<<endl;
temp = temp->next;
}
}
//鏈表反轉
void List::Reverse()
{
if(head==NULL)
return;
Node *curNode=head,*nextNode=head->next,*temp;
while(nextNode!=NULL)
{
temp=nextNode->next;
nextNode->next=curNode;
curNode=nextNode;
nextNode=temp;
}
head->next=NULL;
head=curNode;
}
//清空鏈表
void List::erase()
{
Node* temp = head;
while(temp)
{
Node* p = temp->next;
//temp = temp->next;
delete temp;
temp = p;
head = temp;
length--;
}
}
3、最後就是進行test.cpp文件的編寫進行測試程序!
#include"List.h"
int main(int argc,char** argv)
{
system("color 3F");
List temp;
Info val1,val2,val3,val4,val5,val6;
val1.id = 1;val1.name = "Wang";val2.id = 2;val2.name = "Chao";val3.id = 3;val3.name = "long";
val4.id = 4;val4.name = "Kong";val5.id = 5;val5.name = "zhi";val6.id = 6;val6.name = "shi";
cout<<"Listhead test"<<endl;
temp.ListHead(val1);
temp.Print();
temp.Insert(val2,2);
temp.Print();
temp.Insert(val2,1);
temp.Print();
temp.Insert(val3,2);
temp.Print();
cout<<"Remove test!"<<endl;
temp.Remove(val2);
temp.Print();
cout<<"<**************************>"<<endl;
temp.ListHead(val2);
temp.Print();
cout<<"*************************Last******************"<<endl;
temp.Insert(val4);
//temp.Print();
temp.Insert(val5);
temp.Insert(val6);
temp.Print();
cout<<"*************************Remove**********************"<<endl;
temp.Remove(val5);
temp.Print();
cout<<"<************************Reverse*********************>"<<endl;
temp.Reverse();
temp.Print();
cout<<"***********************erase******************"<<endl;
temp.erase();
temp.Print();
system("pause");
return 0;
}
4、總結
之前都是覺得數據結構特別的難,這次爲了提升自己的算法能力以及代碼的Coding能力,決定再花點時間將《數據結構和算法分析》好好學習一下,平時都是直接調用STL標準庫中現成的API函數,沒什麼感覺,通過對數據結構的學習,可以讓我們從底層的原理實現進行更深層次的瞭解!