个人总结的一些链表知识

总结了一些链表的知识,包括链表创建,反序,逆序输出,解决约瑟夫环(报数问题)

#include<stdio.h>

#include <iostream>
using namespace std;

typedef struct NODE
{
    int value;
NODE *pNext;
}Node,*pNode;


//创建链表
Node* creat(int n)
{
    int t_num = n;
//先定下头指针
pNode t_head = new(Node);
if (NULL == t_head)
{
cout<<"分配内存失败"<<endl;
}
pNode start = new (Node);
t_head->pNext = start;
pNode tmp; 
start->value = 1;
for (int i=1;i<t_num;i++)
{
tmp = new (Node);
int a = i+1;
tmp->value = a;
start->pNext = tmp;
start = tmp;
}
//最后一个
start->pNext = NULL;
return t_head;
}


//链表输出

void pritList(Node* head)
{
pNode start = head->pNext;
   while(start != NULL)
   {
       cout<<start->value;
  start = start->pNext;
   }
   cout<<endl;
}

//链表倒序
Node* reverse(Node* head)
{
if (NULL == head && NULL == head->pNext)
{
return 0;
}
pNode first = head->pNext;
pNode middle = first->pNext;
//倒序以后原有的第一个指向的为空
first->pNext = NULL;
pNode next = NULL;
while(NULL !=middle)
{
   next= middle->pNext;
middle->pNext = first;
first = middle;
middle = next;
}
head->pNext = first;
return head;
}

//创建循环链表
Node* Circlelist(Node* head)
{
if (NULL == head)
{
return 0;
}
if (NULL == head->pNext)
{
        head->pNext = head;
return head;
}
pNode start = head->pNext;
//找到最后一个元素
while(start->pNext!= NULL)
{
start = start->pNext;
}
    start->pNext = head;
    return start->pNext;  

}


//利用循环链表解决约瑟夫环问题
int getnum(Node* s)
{
    while(s->pNext != s)
{
pNode tmp = s->pNext->pNext->pNext;
pNode tmp1,tmp2;
tmp1 = s->pNext;
tmp2 = tmp1->pNext;
tmp1->pNext = tmp;
//删掉对应的节点
free(tmp2);
//移动指针
s = tmp;
}
return s->value;
}

/*利用递归反序输出链表元素,是函数调用栈存储的指针。每次递归调用,函数帧栈里面都存放了指针。
函数递归调用的最后一次,head为NULL,之后函数调用栈依次弹出,获得前面的地址值*/
void reprint(Node *head)
{
if(head!=NULL)
{
reprint(head->pNext);
cout<<head->value;
}
}


/*利用循环实现链表逆序
1找到最后一个节点和倒数第二个节点,把最后一个节点设为头节点的后继
2反转这两个节点
3倒数第三个和第四个节点重复执行步骤2*/
void Inversion_Recursion(Node* p,Node* Head)
{
if(p->pNext==NULL)
{
Head->pNext=p;
return;//找到最后一个节点
}
Inversion_Recursion(p->pNext,Head);
p->pNext->pNext=p;//反转节点
p->pNext=NULL;//第一个节点反转后其后继应该为NULL

}


int main()  
{  
int n;
cin>>n;
if (n>50)
{
return 1;
}
pNode pl = creat(n); 
pritList(pl);  


//逆序排列
pritList(reverse(pl));
Inversion_Recursion(pl->pNext,pl);
        pritList(pl);
pNode start = pl->pNext;
free(pl);
        reprint(start);
//构建循环链表,先把头结点删掉
pNode p2 = Circlelist(start);
//循环链表解决
int b = getnum(p2);
cout<<endl<<b<<endl;
getchar();
getchar();
return 0;  

}  


主要参考的来源:http://blog.csdn.net/kangroger/article/details/20237081  单链表反转(递归和非递归)

                                http://blog.csdn.net/xiaofei2010/article/details/9720145 2012华为机试题目(C/C++)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值