您的位置:首页 > 理论基础 > 数据结构算法

链表相关的算法题大汇总 (1)— 数据结构之链表奇思妙想

2017-09-28 10:21 483 查看
声明:转自http://hi.baidu.com/lanxuezaipiao/item/afc616caf8393a155050585b

基本函数(具体代码实现见后面)

1,构造节点

 //定义节点类型

struct Node

{

    int value;

    Node*next;

};

 

2,分配节点

//之所以要分配节点原因是需要在分配函数中进行初始化,并且也利于判断是否分配成功。

Node* applyNode();

 

3,在头部增加节点

//增加节点在头部(无头结点),返回值的原因是由于传入并非指针的引用。

Node* addNodeH(Node* Head,Node* InsertNode);

 

4,在尾部增加节点

//增加节点在尾部(无头结点),返回值的原因是由于传入并非指针的引用。

Node* addNodeT(Node* Head,Node* InsertNode);

 

5,以升序方式增加节点
Node* addNodeSort(Node* Head,Node* InsertNode);

 

6,构造链表

//没有额外的表头结点。

//选择参数choose分别对应以何种方式构造链表,1为头部增加节点;2为尾部增加节点;3为升序增加节点。

Node* createList(int n,int choose);

 

7,打印链表
void printList(Node*Head);

 

8,释放链表
void freeList(Node*& Head);

 

9,链表节点数
int numOfNodes(Node* Head);

 

10,定位函数

//传入参数i表示第几个节点(从1开始),返回该节点指针

Node* locateNodeI(Node*Head,int i);

 

11,查找函数

//查找值为value的链表

int SearchList(Node*Head,int value);

 

12,删除节点

//删除位置i的节点

bool deleteNodeI(Node*&Head,int i);

 

13,排序函数

//冒泡排序链表,具体的做法是“狸猫换太子”,即只交换节点中的值,对链表结构不做改动。

void sortList(Node*& Head);

 

基本函数代码:

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2,分配节点

//分配节点

//将分配内存和初始化该节点放在一个函数中

Node* applyNode()

{

 Node* newNode;

 if((newNode=(Node*)malloc(sizeof(Node)))==NULL)

 {

  cout<<"分配内存失败!"<<endl;

  ::exit(0);

 }

 //建立该节点信息:

 cout<<"请输入本节点值:"<<endl;

 cin>>newNode->value;

 newNode->next=NULL;

 return newNode;

}

3,在头部增加节点

//在表头增加节点

//在头指针所指向的链表中增加一个节点,插入头部

//这里必须要返回Node*来进行更新,因为传入的Head是Node*类型,而非Node*&

Node* addNodeH(Node* Head,Node* InsertNode)

{

 if(Head==NULL)

 {

  Head=InsertNode;

 }

 else

 {

  InsertNode->next=Head;

  Head=InsertNode;

 }

 return Head;

}

4,在尾部增加节点

//在表尾增加节点

//在头指针所指向的链表中增加一个节点,插入尾部

//这里必须要返回Node*来进行更新,因为传入的Head是Node*类型,而非Node*&

Node* addNodeT(Node* Head,Node* InsertNode)

{

 if(Head==NULL)

 {

  Head=InsertNode;

 }

 else

 {

  Node* p=Head;

  while(p->next!=NULL)

  {

   p=p->next;

  }

  p->next=InsertNode;

 }

 return Head;

}

5,以升序方式增加节点

//以升序增加节点

//这里必须要返回Node*来进行更新,因为传入的Head是Node*类型,而非Node*&

Node* addNodeSort(Node* Head,Node* InsertNode)

{

 if(Head==NULL)

 {

  Head=InsertNode;

 }

 else

 {

  Node* p=Head;

  //注意,这里把(p->value)<(InsertNode->value)放在p->next!=NULL前面是有原因的,这是避免为了考虑在Head->[4]加入[1]的情况

  while((p->value)<(InsertNode->value)&&p->next!=NULL)

  {

   p=p->next;

  }

  if((p->value)>=(InsertNode->value))//因为((p->value)>=(InsertNode->value))而退出!表示在p前增加节点(狸猫换太子)

  {

   //先在p后增加节点

   InsertNode->next=p->next;

   p->next=InsertNode;

   //再交换p和InsertNode的值

   swap(p->value,InsertNode->value);

  }

  else//因为(p->next==NULL)而退出!表示在尾增加节点

  {

   p->next=InsertNode;

  }

 }

 return Head;

}

6,构造链表

//建立n个节点的链表 choose=1,在表头加入,choose=2在表尾加入,choose=3按value值升序加入

Node* createList(int n,int choose)

{

 Node *Head=NULL,*p=NULL;

 for(int i=0;i<n;i++)

 {

  p=applyNode();

  if(choose==1)

  {

   Head=addNodeH(Head,p);

  }

  else if(choose==2)

  {

   Head=addNodeT(Head,p);

  }

  else if(choose==3)

  {

   Head=addNodeSort(Head,p);

  }

 }

 return Head;

}

7,打印链表

//遍历链表并输出

void printList(Node*Head)

{

 Node*p=Head;

 while(p!=NULL)

 {

  cout<<p->value<<"->";

  p=p->next;

 }

 cout<<"NULL"<<endl;

}

8,释放链表

//释放链表

void freeList(Node*& Head)

{

 Node* tmp=Head;

 while(tmp!=NULL)

 {

  Head=Head->next;

  free(tmp);

  tmp=Head;

 }

 Head=NULL; 

}

9,链表节点数

//数节点个数

int numOfNodes(Node* Head)

{

 int count=0;

 while(Head!=NULL)

 {

  count++;

  Head=Head->next;

 }

 return count;

}

10,定位函数

//定位第i个节点,i从1开始

Node* locateNodeI(Node*Head,int i)

{

 //cout<<"定位"<<i<<"位置"<<endl;

 Node* pos=NULL;

 int count=numOfNodes(Head);

 if(i<=0||i>count)

 {

  cout<<"定位越界!"<<endl;

 }

 else 

 {

  pos=Head;

  for(int j=1;j<i;j++)

  {

   pos=pos->next;

  }

 }

 return pos;

}

11,查找函数

//查找值value并返回第一个出现该值的位置,如果需要引用其指针,可以再locate该位置

int SearchList(Node*Head,int value)

{

 Node* p=Head;

 int pos=0;

 bool find=false;

 while(p!=NULL)

 {

  pos++;

  if(p->value==value)

  {

   find=true;

   break;

  }

  p=p->next;

 }

 if(find)

  return pos;

 else 

  return -1;

}

12,删除节点

//删除某位置i的节点

bool deleteNodeI(Node*&Head,int i)

{

 Node* p=locateNodeI(Head,i);

 if(p==NULL)

 {

  return false;

 }

 else

 {

  if(p==Head)//说明p是头节点。

  {

   Head=p->next;

   free(p);

  }

  else

  {

   Node* prep=locateNodeI(Head,i-1);//定位前一个,必定存在 

   prep->next=p->next;

   free(p);

  }

  return true;

 }

}

13,排序函数

//链表排序

//排序的方法是不破坏结构,有“狸猫换太子”的意思,只进行value的交换,不破坏链表结构

void sortList(Node*& Head)

{

 int count=numOfNodes(Head);

 if(count==0||count==1)

 {

  return ;

 }

 //冒泡排序

 bool exchange;

 for(int i=2;i<=count;i++)

 {   

  exchange=false;

  for(int j=count;j>=i;j--)

  {

   Node* p1=locateNodeI(Head,j);

   Node* p2=locateNodeI(Head,j-1);

   if(p1->value<p2->value)

   {

    exchange=true;

    swap(p1->value,p2->value);

   }

  }

  if(!exchange)

   break;

 }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: