学习完链表,做了一遍题,码完代码,能跑的都跑了一遍,检验了一下。答案若有错误,欢迎指出,感谢!
以下是题目和答案(以下题目若没有指出,全是用单向链表)
目录
1. 逆序一个链表
2.如何判断一个链表是否有环
3. 求链表的中间节点,要求只用一重循环。
4. 约瑟夫环的问题
5.class List
6.class List T
这个问题在我 单向链表 博客中已经写出了,这里我就不贴答案了,若想看答案,到我单向链表那里的看reverseList函数即可。
这里主要是一个指针移动是一个节点的单位移动,另一个指针是两个节点为单位移动,如果有环,则肯定能相遇
void checkList(Node*head)
{
Node*p,*q;
p=p->next->next;
q=q->next;
while(q)
{
if(q==p)
{
printf("this is ring");
exit(1);
}
p=p->next->next;
q=q->next;
}
printf("this is not ring");
}
跟上面同理,设一个指针移动是一个节点的单位移动,另一个指针是两个节点为单位移动,当两个节点为单位的指针到达终点时,则另一个节点到达中点
我主要贴一下寻中点的函数,创建、插入函数就不贴了
#include
#include
struct Node
{
int data;
struct Node * next;
};
Node * creatList();
void insertList(Node*head,int data);
Node*searchMiddleList(Node*head);
Node*searchMiddleList(Node*head)
{
head=head->next;
Node * cur=head;
while(cur)
{
cur=cur->next->next;
head=head->next;
}
return head;
}
include
#include"list.h"
#include
using namespace std;
int main()
{
Node * head=creatList();
srand(time(NULL));
for(int i=0;i<10;i++)
{
insertList(head,rand()%10);
}
traverseList(head);
Node*cur=searchMiddleList(head);
cout<data<<", the Node is "<
n个人围成圈,依次编号为1,2,..,n,现在从1号开始依次报数,当报到m时,报m的人退出,下一个人重新从1报起,循环下去,问最后剩下那个人的编号是多少?
这个问题需要用 双向链表 解决,代码如下:
#include
#include
struct DNode
{
int data;
struct DNode*next;
struct DNode*pre;
};
DNode*creatDList();
void traverseDList(DNode*head);
void insertDList(DNode*head,int data);
void deleteDList(DNode*pfind);
DNode* JosephProblem2(DNode*head,int n);//简化
DNode* JosephProblem(DNode*head,int num);
//这里问题问的是编号多少,我这里把最后的节点输出,这里用遍历也能得到最后的编号,因为编号是顺序
PS: 这里我用了C++的文件格式,但是用C语言文件也可以,只要把main函数的输出格式改成C语言格式,就可以了
#include"dlist.h"
DNode*creatDList()
{
DNode*head=(DNode*)malloc(sizeof(DNode));
head->next=head;
head->pre=head;
return head;
}
void traverseDList(DNode*head)
{
DNode* cur=head;
cur=cur->next;
while(cur != head)
{
printf("%d\t",cur->data);
cur=cur->next;
}
}
void insertDList(DNode*head,int data)
{
DNode*cur=(DNode*)malloc(sizeof(DNode));
cur->data=data;
cur->next=head->next;
head->next=cur;
cur->pre=head;
cur->next->pre=cur;
}
void deleteDList(DNode*pfind)
{
pfind->pre->next=pfind->next;
pfind->next->pre=pfind->pre;
free(pfind);
}
DNode* JosephProblem2(DNode* head,int n)//简化
{
int count = 1;
DNode * ph =head->next;
while(1)
{
if(count == n)
{
if((ph->next == head) && (head->next ==ph))
break;
DNode* pp = ph;
ph = ph->next;
deleteDList(pp);
count = 0;
}
else
ph = ph->next;
if(ph == head)
ph = ph->next;
count ++;
}
return ph;
}
DNode* JosephProblem(DNode*head,int num)
{
int count=1;
DNode*cur=head;
cur=cur->next;
while(1)
{
if(cur==head)
{
cur=cur->next;
continue;
}
if(count==num)
{
DNode*th=cur;
if(cur->next != head || cur->pre!=head) //关键一步,判断到这个数的节点是不是最后一个节点,不是的话删除
{
cur=cur->next;
deleteDList(th);
count=1;
}
else //若是最后一个节点,则输出
return cur;
}
else
{
count++;
cur=cur->next;
}
}
}
#include
#include"dlist.h"
using namespace std;
int main()
{
DNode *head=creatDList();
#if 1 //这一步,我主要是想自己键盘输入总编号
int num;
scanf("%d",&num);
for(int i=num;i>0 ;i--)
{
insertDList(head,i);
if(i==1)
break;
}
#endif
#if 0
for(int i=10;i>0;i--)
insertDList(head,i);
#endif
traverseDList(head);
cout<
这里是把List做成一个类,代码如下:
#include
using namespace std;
struct Node
{
int data;
struct Node* next;
};
class List
{
public:
List(); //创建空链表
~List(); //销毁链表
void insertList(int data);
void traverseList();
private:
Node*head;
};
#include "list.h"//函数内容跟之前本质是一样的,这里只写了一部分
List::List()
{
head=new Node;
head->next=NULL;
}
List::~List() //全部销毁
{
Node*t=head;
while(head)
{
head=head->next;
delete t;
t=head;
}
}
void List::insertList(int data)
{
Node*cur=new Node;
cur->data=data;
cur->next=head->next;
head->next=cur;
}
void List::traverseList()
{
Node* ph =head->next;
while(ph)
{
cout<data<next;
}
}
#include
#include"list.h"
using namespace std;
int main()
{
List list;
for(int i=0;i<10;i++)
list.insertList(i);
list.traverseList();
return 0;
}
利用泛型编程实现链表,代码如下:
注意:模板定义很特殊。由template<…>处理的任何东西都意味着编译器在当时不为它分配存储空间,它一直处于等待状态直到被一个模板实例告知。在编译器和连接器的某一处,有一机制能去掉指定模板的多重定义。所以为了容易使用,几乎总是在头文件中放置全部的模板声明和定义,若放在cpp里编译不通过
#include
using namespace std;
template
class myList
{
public:
myList(); //创建链表
~myList();//销毁
void traverseList();
void insertList(T data);
protected:
struct Node
{
T data;
Node*next;
};
private:
Node*head;
};
template //每个函数前都要写,注意格式,其他跟上面的 class 一样
myList::myList()
{
head=new Node;
head->next=NULL;
}
template
myList::~myList()
{
Node*cur=head;
while(head)
{
head=head->next;
delete cur;
cur=head;
}
}
template
void myList::traverseList()
{
Node*cur=head->next;
while(cur)
{
cout<data<next;
}
}
template
void myList::insertList(T data)
{
Node*cur=new Node;
cur->data=data;
cur->next=head->next;
head->next=cur;
}
#include
#include "mylist.h"
using namespace std;
int main()
{
#if 0
myListlist;
for(int i=0;i<10;i++)
list.insertList(i);
list.traverseList();
#endif
myListlist;
for(char i='a';i<'f';i++)
list.insertList(i);
list.traverseList();
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载