链表

来源:互联网 发布:淘宝网显示不了图片 编辑:程序博客网 时间:2024/06/08 16:19

链表

#ifndef __LIST_H__
#define __LIST_H__

#include <iostream>
#include <assert.h>
#include <windows.h>

using namespace std;

template <class T>
struct ListNode{

ListNode<T>* _next;
ListNode<T>* _prev;
T _d;

ListNode<T>(T d)
:_next(NULL)
,_prev(NULL)
,_d(d)
{}
ListNode<T>()
:_next(NULL)
,_prev(NULL)
,_d(NULL)
{}

};

template <class T>
class List{
typedef ListNode<T> Node;
typedef ListNode<T>* pNode;
typedef ListNode<T>* pList;

public:
//带头
List(T d)
{
_root = new Node;

pNode newn = new Node(d);

_root->_next = newn;
_root->_prev = newn;
}
List()
{
_root = new Node;
_root->_prev = _root;
_root->_next = NULL;
}

List(const List<T>& s_d)
{
_root = new Node;
_root->_prev = _root;
pNode s_n = s_d._root;
while (s_n)
{
p_b(s_n->_d);
s_n = s_n->_next;
}
}
void Destory(pNode n)
{
if (n == NULL)
return;
while(n)
{
pNode del = n;
n = n->_next;
cout<<del->_d<<" ";
delete del;
}
cout<<endl;
}

void p_b(T d)
{
pNode tail = _root->_prev;
pNode n = new Node(d);
tail->_next = n;
n->_prev = tail;
n->_next = NULL;

_root->_prev = n;
}

void p_f(T d)
{
pNode n = new Node(d);
pNode p = _root->_next;

_root->_next = n;
n->_prev = _root;

n->_next = p;
p->_prev = n;
}

pNode f_d(T d)
{
if (NULL == _root)
return NULL;
pNode cur = _root->_next;
while (cur)
{
if (cur->_d == d)
{
return cur;
}
cur = cur->_next;
}
return NULL;
}

bool Erase(T d)
{
pNode cur = f_d(d);

if (cur == NULL)
return true;

pNode p = cur->_prev;
pNode t = cur->_next;
delete cur;

p->_next = t;
t ->_prev = p;

return true;
}

bool h_c()//是否带环
{
if (NULL == _root || _root->_next == NULL)
return false;

pNode f_t = _root;
pNode s_y = _root;

do{
f_t = f_t->_next;
if (f_t)
f_t = f_t->_next;
else
return false;
s_y = s_y->_next;
if (s_y == NULL)
return false;
}while(f_t != s_y && f_t && s_y);
if (f_t == NULL || s_y == NULL)
return false;
else
return true;
}
pNode f_m()//换的入口
{
if (NULL == _root || NULL == _root->_next)
return NULL;
pNode s_l = _root;
pNode f_t = _root;
do{
s_l = s_l->_next;
if (s_l == NULL)
return NULL;
f_t = f_t->_next;
if (f_t == NULL)
return NULL;
else
f_t = f_t->_next;
}while(s_l != f_t && f_t && s_l);
if (f_t && s_l)
return s_l;
else
return NULL;
}
size_t f_n_c()//环中节点个数
{
pNode m = this->f_m();
if (m == NULL || _root == NULL)
return 0;

pNode cur = _root;
size_t cnt = 0;

while (cur != m){
cur = cur->_next;
}

do{
cnt++;
cur = cur->_next;
}while(m != cur);
return cnt;
}
pNode f_e()//环的入口
{

if (!h_c())
return NULL;
else{
pNode c = _root;
pNode m = f_m();
do
{
c = c->_next;
m = m->_next;
}while(c != m);
return m;
}
}
pNode f_t_m(List<T>& s_d)//判断是否相交
{
pNode d_m = f_e(); //f_list_entry_node
pNode s_m = s_d.f_e();//s_list_entry_node

pNode s_t = s_d._root;
s_t = s_t->_prev;//s_list_tail

pNode f_t = _root->_prev;//f_list_tail

if (d_m == NULL || s_m == NULL)//no close both

{
pNode tmp = NULL;
if (s_t->_next || f_t->_next)
{
if (s_t->_next == NULL)
tmp = f_t->_next;
else
tmp = s_t->_next;
printf("不带环,相交,相交节点为%d\n",tmp->_d);

}
else{
printf("不带环,不相交\n");
return NULL;
}
}


else if (d_m && s_m) //都带环
{
if (d_m == s_m){ //相交
if (s_t->_next == d_m)
{
printf("带环相交,相交节点为%d\n",f_t->_next->_d);
return f_t->_next;
}
else{
printf("带环相交,相交节点为%d\n",s_t->_next->_d);
return s_t->_next;
}
}
else{
pNode tmp = s_m->_next;
while (tmp != s_m)
{
if (tmp == d_m){//相交带环
if (s_t->_next == s_m){
printf("相交带环,相交点为%d\n",f_t->_next->_d);
return f_t->_next;
}
else{
printf("相交带环,相交点为%d\n",s_t->_next->_d);
return s_t->_next;
}
}
else{
printf("都带环但不相交\n");
return NULL;
}
}
}
}
else
printf("一个带环一个不带\n");
}
~List()
{
if (!this->h_c())
Destory(_root);
else
cout<<" have close!\n"<<endl;
}

protected:
pList _root;
};

//代环


#endif //__LIST_H__

List.h

#ifndef     __SQLIST_H__
#define __SQLIST_H__

#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <assert.h>

enum Station
{
STATIONONE, //两条链表布带环不相交
STATIONTWO, //两条链表不带环相交
STATIONTHREE, //一条带环一条不带不相交
STATIONFOUR, //两条链表都带环不相交
STATIONFIVE, //都带环在环的外面相交
STATIONSIX, //都带环在环的里边相交
};

typedef int DataType;
typedef struct Node
{
struct Node* next;
DataType data;
}Node, *pList, *pNode;

void InitList(pList* pplist);
int GetListLength(pList plist);
void PushBack(pList* pplist, DataType data);
void PopBack(pList* pplist);
void PushFront(pList* pplist, DataType data);
void PopFront(pList* pplist);
void PrintList(pList plist);
pNode Find(pList plist, DataType data);
void Remove(pList* pplist, DataType data);
void RemoveAll(pList* pplist, DataType data);
void Insert(pList* pplist, pNode pos, DataType data);
void Erase(pList* pplist, pNode pos);
void DestoryList(pList *pplist);

//在当前节点前插入一个数据d
void InsertFrontNode (pNode pos, DataType data);
//删除无头单链表的非尾节点
void EraseNotTail(pNode pos);
//逆置链表
void ReverseList(pList* pplist);
//删除倒数第K个节点(k > 1 && k < 总结点数)时间复杂度O(N)
void DelKNode(pList* pplist, int num);
//查找链表的中间节点
pNode FindMidNode(pList plist);
//递归实现逆序打印字符串
void PrintReversely(pList plist);
//约瑟夫环问题
pNode JosephCycle(pList* pplist, int num);
//检查链表是否带环
pNode CheckCycle(pList plist);
//若带环求环的长度
int GetCircleLength(pNode meet);
//若带环求环的入口
pNode GetCycleEntryNode(pList plist, pNode MeetNode);
//检测两条链表是否带环
int CheckCross(pList list1, pList list2);
//合并两个有序链表--非递归实现
pList Merge(pList list1, pList list2);
//合并两个有序链表--递归实现
pList Merge2(pList l1, pList l2);




typedef struct ComplexNode
{
DataType data;
struct ComplexNode* next;
struct ComplexNode* random;
}ComplexNode, *pComplexNode, *pComplexList;

pComplexNode CreatComplexNode(DataType data);
void PrintComplexList(pComplexList plist);
pComplexList CloneComplexNode(pComplexList plist);
void InitComplexList(pComplexList* pplist);
void DestroyComplexList(pComplexList* pplist);

#endif //__SQLIST_H__

list.c

#include "SqList.h"

void InitList(pList* pplist)
{
assert(pplist != NULL);
*pplist = NULL;
}

int GetListLength(pList plist)
{
pNode cur = plist;
int count = 1;
if (plist == NULL)
{
return 0;
}
while (cur->next != NULL)
{
count++;
cur = cur->next;
}
return count;
}
pNode BuyNode(DataType data)
{
pNode New = (pNode)malloc(sizeof(Node));
if (New == NULL)
{
perror("malloc");
return NULL;
}
New->data = data;
New->next = NULL;
return New;
}
void PushBack(pList* pplist, DataType data)
{
pNode NewNode = BuyNode(data);
pNode cur = *pplist;
assert( pplist != NULL);
if (NULL == *pplist) //空链表
{
*pplist = NewNode;
return;
}
else if (NULL == cur->next) //含有一个节点的链表
{
cur->next = NewNode;
return;
}
while (NULL != cur->next->next) //两个以上
{
cur = cur->next;
}
cur->next->next = NewNode;
}

void PopBack(pList *pplist)
{
pNode cur = *pplist;
if (NULL == cur)
{
printf("None\n");
return;
}
else if(NULL == cur->next)
{
free(cur);
*pplist = NULL;
return;
}
while (NULL != cur->next->next)
{
cur = cur->next;
}
free(cur->next);
cur->next = NULL;
}

void PushFront(pList* pplist, DataType data)
{
int tmp = 0;
pNode cur = *pplist;
pNode NewNode = BuyNode(data);
assert(pplist);
if (NULL == cur)
{
*pplist = NewNode;
return;
}
else if(NULL != cur)
{
tmp = cur->data;
cur->data = NewNode->data;
NewNode->data = tmp;
if (NULL == cur->next)
{
cur->next = NewNode;
return;
}
else
{
NewNode->next = cur->next;
cur->next = NewNode;
return;
}
}
}
void PopFront(pList* pplist)
{
pNode cur = *pplist;
assert(pplist);
if (NULL == cur)
{
printf("None\n");
return;
}
else if (NULL == cur->next)
{
free(cur);
*pplist = NULL;
return;
}
else
{
*pplist = cur->next;
free(cur);
}
}

void PrintList(pList plist)
{
pList list = plist;
if (NULL == plist)
{
printf("None\n");
return;
}
printf("LIST:");
while (list)
{
printf("->%d",list->data);
list = list->next;
}
printf("\n");
}

pNode Find(pList plist, DataType data)
{
pList list = plist;
if (NULL == list)
{
//printf("None\n");
return NULL;
}
while (list != NULL)
{
if (list->data == data)
{
// printf("FIND\n");
return list;
}
list = list->next;
}
//printf("HAVEN'T\n");
return NULL;
}

void Remove(pList* pplist, DataType data)
{
pNode cur = *pplist;
pNode del = *pplist;
assert(pplist);
if (NULL == *pplist) //空链表
{
printf("None\n");
return;
}
if (NULL == cur->next)
{
if (data == cur->data)
{
free(cur);
*pplist = NULL;
return;
}
else
{
return;
}
}
while (cur)
{
if (data = cur->data)
{
if (*pplist == cur)
{
*pplist = cur->next;
free(cur);
return;
}
else if (*pplist != cur)
{
del = cur->next;
cur->data = cur->next->data;
if (del->next != NULL)
{
cur->next = del->next;
free(del);
return;
}
free(del);
cur->next = NULL;
}
}
cur = cur->next;
}
}

void RemoveAll(pList* pplist, DataType data)
{
pNode cur = *pplist;
pNode del = NULL;
assert(pplist);
if (NULL == cur)
{
printf("None\n");
return;
}
while ( ( del = Find(*pplist, data) ) != NULL )
{
Erase(pplist,del);
}
//{
// if (NULL == find->next)
// {
// free(find);
// *pplist = NULL;
// return;
// }
// else if (NULL != find->next)
// {
// if (find == *pplist)
// {
// *pplist = find->next;
// free(find);
// find = *pplist;
// }
// else if(NULL != find->next->next)
// {
// cur = find->next->next;
// free(find->next);
// find = cur;
// }
// }
// if(find->next->next == NULL)
// {
// free(find->next);
// find->next = NULL;
// }
//}
//if (find->next->data == data)
//{
// free(find->next);
// find->next = NULL;
//}
}

void Insert(pList* pplist, pNode pos, DataType data)
{
pNode InNode = BuyNode(data);
pNode cur = NULL;
assert(pplist);
assert(pos);
if (pos->next ==NULL)
{
pos->next = InNode;
return;
}
else
{
cur = pos->next;
pos->next = InNode;
InNode->next = cur;
return;
}
}

void Erase(pList* pplist, pNode pos)
{
pNode del = NULL;
pNode cur = *pplist;
assert(pplist);
if (NULL == cur)
{
return;
}
if (NULL != pos->next)
{
del = pos->next;
pos->data = pos->next->data;
if (pos->next->next != NULL)
{
pos->next = pos->next->next;
free(del);
}
else
{
free(del);
pos->next = NULL;
}
}
else if(NULL == pos->next)
{
PopBack(pplist);
}
return;
}
void DestoryList(pList *pplist)
{
pNode cur = *pplist;
pNode del = NULL;
assert(pplist != NULL);
if ( NULL == cur)
{
return;
}
else if(NULL == cur->next)
{
free(cur);
*pplist = NULL;
return;
}
while (cur)
{
del = cur;
cur = cur->next;
free(del);
}
*pplist = NULL;
}
void InsertFrontNode (pNode pos, DataType data)
{
pNode NewNode = BuyNode(data);
DataType tmp = 0;
tmp = pos->data;
pos->data = NewNode->data;
NewNode->data = tmp;
if (NULL == pos->next)
{
pos->next = NewNode;
}
else
{
NewNode->next = pos->next;
pos->next = NewNode;
}
}
void EraseNotTail(pNode pos)
{
pNode cur = pos;
pNode tail = NULL;
assert(NULL != pos);
if (NULL == pos->next)
{
return;
}
tail = cur->next;
cur->data = tail->data;
if (NULL == tail->next)
{
free(tail);
cur->next =NULL;
return;
}
cur->next = tail->next;
return;
}
void ReverseList(pList* pplist)
{
pNode cur = *pplist;
pNode tail = NULL;
pNode tmp = NULL;
pList NewList = NULL;
assert(NULL != pplist);
if (NULL == cur || NULL == cur->next)
{
return;
}
while (cur)
{
tail = cur->next;
if (NULL == NewList)
{
NewList = cur;
NewList->next = NULL;
}
else
{
tmp = NewList;
NewList = cur;
NewList->next = tmp;
}
cur = tail;
}
*pplist = NewList;
}
pNode FindMidNode(pList plist)
{
pNode Slow = plist;
pNode Fast = plist;
if (NULL == plist)
{
return NULL;
}
else if(NULL == plist->next)
{
return plist;
}
while (Fast->next)
{
Slow = Slow->next;
Fast = Fast->next->next;
if (NULL == Fast)
{
break;
}
}
return Slow;
}

void DelKNode(pList* pplist, int num)
{
pNode Fast = *pplist;
pNode Slow = *pplist;
assert(pplist);
if (*pplist == NULL)
{
return;
}
while (Fast)
{
--num;
if(num < 0)
{
Slow=Slow->next;
}
Fast = Fast->next;
}
if (num > 0)
{
return;
}
else
{
Erase(pplist, Slow);
}
return;
}
void PrintReversely(pList plist)
{
pNode cur = plist;
if ( (NULL == cur) || (NULL == cur->next) )
{
printf("%d ", cur->data);
return;
}
else
{
PrintReversely(cur->next);
}
printf("%d ", cur->data);

}
pNode JosephCycle(pList* pplist, int num)
{
pNode cur = *pplist;
pNode del = NULL;
int i = 0;
assert( NULL != pplist);
while (cur != cur->next)
{
for (i = 0; i < num - 1; i++)
{
cur = cur->next;
}
cur->data = cur->next->data;
del = cur->next;
cur->next = cur->next->next;
free(del);
}
return cur;
}
pNode CheckCycle(pList plist)
{
pNode Fast = plist;
pNode Slow = plist;
if (NULL == plist)
{
return NULL;
}
if (NULL == plist->next)
{
return NULL;
}
do
{
Slow = Slow->next;
Fast = Fast->next->next;
if (NULL == Fast || NULL == Fast->next)
{
return NULL;
}
}while (Fast != Slow);
return Slow;
}
int GetCircleLength(pNode meet)
{
pNode cur = meet;
int count = 0;
if (NULL == meet)
{
return 0;
}
do
{
++count;
cur = cur->next;
}while(meet != cur);
return count;
}
pNode GetCycleEntryNode(pList plist, pNode MeetNode)
{
pNode Start = plist;
pNode Meet = MeetNode;
if (MeetNode == NULL)
{
return NULL;
}
while (Start != Meet)
{
Start = Start->next;
Meet = Meet->next;
}
return Meet;
}
int CheckCross(pList list1, pList list2)
{
pNode NodeOne = CheckCycle(list1);
pNode NodeTwo = CheckCycle(list2);
if (NULL == NodeOne && NULL == NodeTwo) //都不带环分两种情况1.两链表不相交 。 2.两链表相交。
{
pNode cur1 = list1;
pNode cur2 = list2; //有一个为空,则不相交
while (cur1)
{
cur1 = cur1->next;
}
while (cur2)
{
cur2 = cur2->next;
}
if (cur1 == cur2)
{
return STATIONTWO;
}
else
{
return STATIONONE;

}
}
else if(NodeOne && NodeTwo) //两个都带环,分三种情况。1.带环不相交。2.相交点不在环上。3.相交点在环上。
{
int NumOne = GetCircleLength(NodeOne);
int NumTwo = GetCircleLength(NodeTwo);
if (NumOne == NumTwo) //两环个数相同
{
pNode EnterOne = GetCycleEntryNode(list1, NodeOne);
pNode EnterTwo = GetCycleEntryNode(list2, NodeTwo);
if (EnterOne == EnterTwo) //两个环的入口相同
{
return STATIONFIVE;
}
else
{
do
{
EnterOne = EnterOne->next;
--NumOne;
}while(EnterOne != EnterTwo && NumOne);
if (NumOne <= 0)
{
return STATIONFOUR;
}
else
return STATIONSIX;
}
}
else //两环个数不同肯定不相交。
{
return STATIONFOUR;
}
}
else //一个带环一个不带,两者肯定不相交
{
return STATIONTHREE;
}
}
pComplexNode CreatComplexNode(DataType data)
{
pComplexNode New = (pComplexNode)malloc(sizeof(ComplexNode));
if (NULL == New)
{
perror("malloc");
return NULL;
}
New->data = data;
New->next = NULL;
New->random = NULL;
return New;
}
void PrintComplexList(pComplexList plist)
{
pComplexNode cur = plist;
if (NULL == cur)
{
printf("None\n");
return;
}
while (cur)
{
if (cur->next == NULL)
{
printf("%d->next->NULL->random->%d ",cur->data,cur->random->data);
}
else if(NULL == cur->random)
{
printf("%d->next->%d->random->NULL ",cur->data, cur->next->data );
}
else
{
printf("%d->next->%d->random->%d ",cur->data, cur->next->data ,cur->random->data);
}
cur = cur->next;
}
}
pComplexList CloneComplexNode(pComplexList plist)
{
pComplexList Clone = NULL;
pComplexList cur = plist;
pComplexNode tail = NULL;
pComplexNode prev = NULL;
pComplexNode New = NULL;
if (NULL == cur)
{
return NULL;
}
while (cur) //加倍原来的节点
{
New = CreatComplexNode(cur->data);
New->next = cur->next;
cur->next = New;
cur = cur->next->next;
}
cur = plist;
while (NULL == cur->next) //链接random
{
cur->next->random = cur->random->next;
cur = cur->next->next;
}

//断链,好JB难啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//cur = plist;
//prev = cur->next;
//Clone = prev;
//while (prev->next)
//{
// tail = prev->next;
// cur->next = prev->next;
// prev->next = tail->next;
// //cur = cur->next;
// tail = tail->next;
return Clone;
}


void InitComplexList(pComplexList* pplist)
{
assert(NULL != pplist);
*pplist = NULL;
}
void DestroyComplexList(pComplexList* pplist)
{
pComplexNode cur = *pplist;
pComplexNode del = *pplist;
assert(NULL != pplist);
if (NULL == *pplist)
{
return;
}
while(cur)
{
cur =cur->next;
free(del);
del = cur;
}
*pplist = NULL;
}
pList Merge(pList list1, pList list2)
{
pList NewList = NULL;
pNode cur1 = list1;
pNode cur2 = list2;
pNode New = NULL;
if ( NULL == list1 || NULL == list2) //两条链表至少有一条为空
{
if (NULL == list1)
{
return list2;
}
else
return list1;
}
else
{
if (cur1->data > cur2->data)
{
NewList = cur2;
cur2 = cur2->next;
}
else
{
NewList = cur1;
cur1 = cur1->next;
}
}
New = NewList;
while (cur1 && cur2)
{
if (cur1->data >= cur2->data)
{
New->next = cur2;
cur2 = cur2->next;
}
else
{
New->next = cur1;
cur1 = cur1->next;
}
New = New->next;
}
if (cur1 == NULL)
{
New->next = cur2;
}
else if(cur2 == NULL)
{
New->next = cur1;
}
return NewList;
}
pList Merge2(pList list1, pList list2)
{
pList NewList = NULL;
pNode cur1 = list1;
pNode cur2 = list2;
if (NULL == cur1)
{
return cur2;
}
else if(NULL == cur2)
{
return cur1;
}

if (cur1->data >= cur2->data)
{
NewList = cur2;
NewList->next = Merge2(cur1,cur2->next);
}
else
{
NewList = cur1;
NewList->next = Merge2(cur1->next,cur2);
}
return NewList;
}
原创粉丝点击