链表相关的算法题大汇总 (1)— 数据结构之链表奇思妙想
2017-09-28 10:21
483 查看
声明:转自http://hi.baidu.com/lanxuezaipiao/item/afc616caf8393a155050585b
//定义节点类型
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;
}
}
基本函数(具体代码实现见后面)
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;
}
}
相关文章推荐
- 链表相关的算法题大汇总 — 数据结构之链表奇思妙想
- 链表相关的算法题大汇总 — 数据结构之链表奇思妙想
- 链表相关的算法题大汇总 — 数据结构之链表奇思妙想
- 链表相关的算法题大汇总(2) — 数据结构之链表奇思妙想
- 数据结构之链表——环相关问题及解决思路汇总
- 数据结构及算法练习--链表相关
- 【linux驱动笔记】字符设备驱动相关数据结构与算法
- 数据结构与算法之链表(三)单链表反转
- 数据结构与算法-双链表(初级)
- 数据结构与算法学习之队列及队列的相关操作
- 数据结构与算法 - 链表
- 数据结构与算法之链表
- 数据结构与算法以及刷题leetocde 007 查找表 set和map相关
- 数据结构与算法(5、链表的拼接)
- 数据结构之链表合并算法
- 算法与数据结构之线性结构的相关知识,简单易懂。
- 数据结构与算法JavaScript - 链表
- 【数据结构】单链表插入算法
- 数据结构:单链表操作之如何判断链表是否带环及相关操作
- 【数据结构与算法】HashTable相关操作实现(附完整源码)