單鏈表

線性表的鏈式表示:用一組任意的存儲單元存儲線性表的數據元素。

鏈表的種類:鏈表的種類多,如單鏈表,雙向鏈表,靜態鏈表,循環鏈表等等,本篇只介紹單鏈表。

單鏈表的示意圖:


存儲密度=結點數據本身所佔的存儲量/結點結構所佔的存儲總量,所以單鏈表的存儲密度爲50%,因爲需要存儲指針數據。

頭結點與首元結點:首元結點是鏈表中第一個元素結點,而頭結點是附設在首元結點之前的一個結點,附設頭結點的好處是插入和刪除時不需要對首元結點做特殊處理。

建立單鏈表有兩種方法:頭插法和尾插法,頭插法存儲的元素順序與輸入順序相反,而尾插法一致。故可採取頭插法的方式將單鏈表中數據元素逆置。

單鏈表的具體實現:data域採取string類型。
#include<iostream>
#include<string>
#include<cstdlib>


using namespace std;
struct LinkList
{
string data;
LinkList *next;
};




class LinkListClass
{
private:
LinkList *head;
public:
LinkListClass();
~LinkListClass();
void CreateLinkListF();                   //頭插法
void CreateLinkListR();  //尾插法
bool Delete(int i);
bool Insert(int i,string &data);
LinkList* Search(string data);
int GetLength();
void Display();
friend void Merge(LinkListClass &L1,LinkListClass &L2,LinkListClass &L3);//二路合併
};


LinkListClass::LinkListClass()
{
head=new LinkList();
head->next=NULL;
}


LinkListClass::~LinkListClass()
{
LinkList *p,*q;
p=head;q=head->next;
while(q)
{
delete p;
p=q;
q=q->next;
}
delete p;
}


void LinkListClass::CreateLinkListF()
{
cout<<"輸入元素個數:";
int n;
cin>>n;
LinkList *p,*q; 
for(int i=0;i<n;i++)
{
p=new LinkList();
cin>>p->data;
q=head->next;
head->next=p;
p->next=q;
}
}


void LinkListClass::CreateLinkListR()
{
cout<<"輸入元素個數:";
int n;
cin>>n;
LinkList *p,*q;
q=head; 
for(int i=0;i<n;i++)
{
p=new LinkList();
cin>>p->data;
q->next=p;
p->next=NULL;
q=p;
}
}
bool LinkListClass::Delete(int i)
{
if(i<1||i>GetLength())return false;
int j;
LinkList *p,*q;
for(p=head,j=0;j<i-1;j++,p=p->next);
q=p->next;
p->next=q->next;
delete q;
return true;
}


bool LinkListClass::Insert(int i,string &data)
{
LinkList *p,*q;
if(i<0||i>GetLength())return false;
p=new LinkList();
p->data=data;
int j;
for(q=head,j=0;j<i-1;j++,q=q->next);


p->next=q->next;
q->next=p;


return true;
}


LinkList* LinkListClass::Search(string data)
{


LinkList *p;
p=head->next;
while(p!=NULL)
{
if(p->data==data)return p;
else p=p->next;
}
if(p==NULL)return NULL;
}


int LinkListClass::GetLength()
{
LinkList *p;
int i;
for(i=0,p=head->next;p!=NULL;i++,p=p->next);
return i;
}


void LinkListClass::Display()
{
LinkList *p;
for(p=head->next;p!=NULL;p=p->next)
{
cout<<p->data<<" ";
}
cout<<endl;
}


void Merge(LinkListClass &L1,LinkListClass &L2,LinkListClass &L3)
{
LinkList *p,*q,*t,*p1,*q1;
t=L3.head;
p=L1.head->next;q=L2.head->next;
L1.head->next=NULL;
L2.head->next=NULL;//將L1和L2置爲空表
while(p && q)
{
if(p->data.compare(q->data)<0)
{
p1=p->next;
t->next=p;
t=p;
p=p1;
}
else
{
q1=q->next;
t->next=q;
t=q;
q=q1;
}
}
while(p)
{
p1=p->next;
t->next=p;
t=p;
p=p1;
}
while(q)
{
q1=q->next;
t->next=q;
t=q;
q=q1;
}
t->next=NULL;
}
/*
算法分析:時間複雜度爲O(n+m),n,m爲L1和L2的鏈表長度。
 空間複雜度爲O(1);
*/
int main()
{
int n;
LinkListClass L;
while(1)
{
cin>>n;string data;LinkList *p;
switch(n)
{
case 1:L.CreateLinkListF();break;
case 2:L.CreateLinkListR();break;
case 3:cout<<L.GetLength()<<endl;break;
case 4:int i;
  cin>>i;
  L.Delete(i);break;
case 5:
  cin>>i>>data;
  L.Insert(i,data);break;
case 6:cin>>data;
p=L.Search(data);
if(p!=NULL)cout<<p->data;
else cout<<"NO";break;
case 7:{LinkListClass L1,L2,L3;
  L1.CreateLinkListR();
  L2.CreateLinkListR();
  Merge(L1,L2,L3); L3.Display();
  break;}
case 8:L.Display();
}
}


return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章