码迷,mamicode.com
首页 > 其他好文 > 详细

单链表

时间:2016-08-04 21:16:04      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:

 

#include <iostream>
#include <stack>
using namespace std;

//定义结点结构体
struct Node
{
int data;
struct Node * next;
} ;


//创建单链表
Node * Create(int n)
{
int i;
Node *head,*p1,*p2;
head=NULL;
for(i=1;i<=n;i++)
{
p1=(Node *)malloc(sizeof(Node));
printf("请输入链表中的第%d个数:",i);
scanf("%d",&p1->data);
if(head==NULL)//判断是否为空链表
{
head=p1;
p2=p1;
}
else
{
p2->next=p1;
p2=p1;
}
p2->next=NULL;
}
return head;
}

//单链表测长
int GetListLength(Node * head)
{
Node * p = head;
int count = 0;
while(p)
{
p = p->next;
++count;
}
return count;
}

//打印单链表
void PrintList(Node * head)
{
Node * p = head;
while(p)
{
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}

//在单链表中某个位置之前插入一个元素
Node* InsertList(Node * head,int pos)
{
int i;
Node * p1,* p2;
Node * ptmp;
int length = GetListLength(head);
Node *pNewNode = (Node*)malloc(sizeof(Node));
printf("please input the num you want to insert:\n");
scanf("%d",&pNewNode->data);


//如果是空表
if(NULL ==head )
{
printf("the List is empty,only first position can be insert!\n");
pNewNode->next = NULL;
head = pNewNode;
return head;
}

if( pos<=0 || pos>length)
{
printf("the insert position is illegal!\n");
}
else
{
p1 = head;
for(i=1;i<pos;i++)
{
p2 = p1;
p1 = p1->next;
}
p2->next = pNewNode;
pNewNode->next = p1;

}
return head;

}

//删除一个结点
Node * DeleteList(Node* head,int pos)
{

int i;
Node * p1,* p2;
//如果是空表
if(NULL == head )
{
printf("the List is empty,you can not delete any item!\n");
return head;

}

int length = GetListLength(head);
if( pos<=0 || pos>length)
{
printf("the insert position is illegal!\n");
}
else
{
p1 = head;
for(i=1;i<=pos;i++);
{
p2 = p1;
p1 = p1->next;
}
p2->next = p1->next;
free(p1);
p1 = NULL;

}
return head;
}

//逆序链表,使用循环的方法
Node * ReverseList1(Node* head)
{
Node *prev,*p,*tmp;

if(head == NULL || head->next == NULL)
{
printf("you can not or you need not reverse this list!\n");
return head;
}
else
{
p = head;
prev = NULL;
while(p)
{

tmp = p->next;
p->next = prev;
prev = p;
p = tmp;
}
return prev;
}
}

//逆序链表,使用递归的方法
Node * ReverseList2(Node* head)
{
Node * pNewHead;

if(head == NULL || head ->next == NULL)
return head;

pNewHead = ReverseList2(head->next);
head->next->next = head;
head->next = NULL;
return pNewHead;
}

//查找倒数第k个结点
Node * FindLastK(Node * head ,int k)
{
if(head == NULL || k ==0)
return head;

Node *pAhead = head;
Node *pBhead = head;

// 前面的指针先走到正向第k个结点
while(pAhead != NULL && k >1)
{
pAhead = pAhead->next;
--k;
}

// 前后两个指针一起向前走,直到前面的指针指向最后一个结点
while(pAhead->next!= NULL)
{
pAhead = pAhead->next;
pBhead = pBhead->next;
}
return pBhead;
}

//查找中间结点
Node * FindMid(Node * head)
{
if(head == NULL || head->next == NULL)
return head;
Node * PAhead = head;
Node * pBhead = head;

while(PAhead->next != NULL)
{
PAhead = PAhead->next;
pBhead = pBhead->next;
if(PAhead->next != NULL)
PAhead = PAhead->next;
}
return pBhead;
}

// 从尾到头打印链表,使用栈 ,注意需要包含头文件:#include<stack>
void RPrintList1(Node * head)
{
stack<Node *> s;
Node * pNode = head;
while(pNode != NULL)
{
s.push(pNode);
pNode = pNode->next;
}
while(!s.empty())
{
pNode = s.top();
printf("%d\t", pNode->data);
s.pop();
}
}


// 从尾到头打印链表,使用递归
void RPrintList2(Node * head)
{
if(head == NULL)
{
return;
}
else
{
RPrintList2(head->next);
printf("%d\t", head->data);
}
}

//判断链表中是否有环
//如果一个链表中有环,也就是说用一个指针去遍历,是永远走不到头的。因此,我们可以用两个指针去遍历
//一个指针一次走两步,一个指针一次走一步,如果有环,两个指针肯定会在环中相遇。

bool HasCycle(Node * head)
{
Node * pFast = head;
Node * pslow = head;
while(pslow->next != NULL && pFast->next != NULL)
{
pFast = pFast->next->next;
pslow = pslow->next;
if(pFast == pslow)
return true;
}
return false;
}

// 从单链表中删除指定指针的结点
Node* Delete(Node * head, Node * pToBeDeleted)
{
if(pToBeDeleted == NULL || head == NULL)
return head;

//不是尾结点
if(pToBeDeleted->next != NULL)
{
pToBeDeleted->data = pToBeDeleted->next->data;
Node * ptmp = pToBeDeleted->next;
pToBeDeleted->next = pToBeDeleted->next->next;
free (ptmp);
ptmp= NULL;
}
else
{
//链表中只有一个结点
if(pToBeDeleted == head)
{
free(head);
head = NULL;
}
else
{
Node * ptmp = pToBeDeleted->next;
free(ptmp);
ptmp = NULL;
pToBeDeleted = NULL;

}
}

return head;
}


int main()
{
//创建链表并打印,统计链表长度
Node *head = Create(5);
printf("the list you create is\n");
PrintList(head);
int num = GetListLength(head);
printf("the length of the list is:%d \n",num);

//插入链表并打印
Node * pInser = NULL;
pInser = InsertList(head,3);
printf("the list after you insert is:\n");
PrintList(pInser);


//删除链表元素并打印
Node * pDele = DeleteList(head,2);
printf("the list after you insert is:\n");
PrintList(pDele);


//链表逆序
/*Node * PRever1 = ReverseList1(head);
printf("the list after you reverse by loop method is:\n");
PrintList(PRever1); */

Node * PRever2 = ReverseList2(head);
printf("the list after you reverse by recursive method is:\n");
PrintList(PRever2);

//查找倒数第k个结点
Node * PFindK = FindLastK(head ,2);
printf("the last k position‘s data is:%d\n",PFindK->data);

//查找中间结点
Node * PMid = FindMid(head);
printf("the mid position‘s data is:%d\n",PMid->data);

//逆序打印链表
printf("reverse print the list by stack method\n");
RPrintList1(head);
printf("reverse print the list by recursive method\n");
RPrintList2(head);


if(HasCycle(head))
printf("this list has a cycle\n");
else
printf("this list has no cycle\n");


}

单链表

标签:

原文地址:http://www.cnblogs.com/chay/p/5738211.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!