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

 

声明:转自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;
 }
}

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页