您的位置:首页 > 其它

链表的一些常用操作

2015-01-21 14:02 190 查看
// LinkListDemo.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <iostream>
#include <assert.h>
using namespace std;

#define random(x) (rand()%x)

#define INVALIDVALUE -1000000000

typedef struct LNode
{
int data;
LNode* pnext;
LNode(){data = INVALIDVALUE; pnext = NULL;}
}BINODE, *PBINODE;

class CLinkList
{
public:
CLinkList();
~CLinkList();

private:
CLinkList(const CLinkList &rh);
CLinkList& operator=(const CLinkList &rh);

public:

//
// 函数功能:获取链表中元素个数
int getcount();

//
// 函数功能:清空链表
void clear();

//
// 函数功能:获取链表第nPos个位置上的结点指针
PBINODE getnode(int nPos);

//
// 函数功能:获取中间结点
// 注:这个获取的方式是通过连个指针,一个步长为1,另一个步长为2.步长为2的走到底后步长为1的正好到中间
int getmid();

//
// 函数功能:获取根结点
PBINODE getroot();

//
// 函数功能:在nPos位置上插入元素
bool insertnode(PBINODE pNode, int nPos);

//
// 函数功能:在nPos位置上插入元素
bool insertnode(int value, int nPos);

//
// 函数功能:删除第nPos位置上的元素
bool deletenode(int nPos);

//
// 函数功能:打印链表
void printnode();

//
// 函数功能:值为nValue元素的第n次出现的位置
int locate(int nvalue,int n);

//
// 函数功能:逆置
void reverse();

//
// 函数功能:排序(冒泡排序法)
void BubbleSort();

private:
PBINODE m_root;
int m_nCount;
};

CLinkList::CLinkList()
{
m_root = new LNode();
m_nCount = 0;
assert(m_root != NULL);
}

CLinkList::~CLinkList()
{
clear();
}

//
// 函数功能:获取链表中元素个数
int CLinkList::getcount()
{
return m_nCount;
}

//
// 函数功能:清空链表
void CLinkList::clear()
{
PBINODE pNode = m_root;
PBINODE ptmpNode = NULL;
while(pNode != NULL)
{
ptmpNode = pNode->pnext;
delete pNode;
pNode = ptmpNode;
}
m_root = NULL;
}

//
// 函数功能:获取根结点
PBINODE CLinkList::getroot()
{
return m_root;
}

//
// 函数功能:获取链表第nPos个位置上的结点指针
PBINODE CLinkList::getnode(int npos)
{
if (m_root == NULL)
{
return NULL;
}

if (npos > getcount())
{
return NULL;
}

PBINODE pNode = m_root;
int i = 0;
while (i < npos)
{
pNode = pNode->pnext;
i++;
}
return pNode;
}

//
// 函数功能:获取中间结点
// 注:这个获取的方式是通过连个指针,一个步长为1,另一个步长为2.步长为2的走到底后步长为1的正好到中间
int  CLinkList::getmid()
{
/*
// 方法一,通过对象本身的个数来求中间的元素
if (getcount() <= 1)
{
return INVALIDVALUE;
}

int nMid = getcount() / 2;

PBINODE pNode = getnode(nMid);
assert(pNode != NULL);

return pNode->data;
*/

PBINODE pNode = getroot();
PBINODE pTNode = pNode->pnext;
while (pTNode != NULL)
{
pNode = pNode->pnext;
pTNode = pTNode->pnext;
if (pTNode != NULL)
{
pTNode = pTNode->pnext;
}
}
assert(pNode != NULL);
return pNode->data;
}

//
// 函数功能:在nPos位置上插入元素
bool CLinkList::insertnode(PBINODE pNode, int nPos)
{
if (pNode == NULL || nPos <= 0 || nPos > getcount() + 1)
{
return false;
}

PBINODE pPreNode = getnode(nPos - 1);
assert(pPreNode != 0);
PBINODE ptmp = pPreNode->pnext;
pPreNode->pnext = pNode;
pNode->pnext = ptmp;
m_nCount++;

return true;
}

//
// 函数功能:在nPos位置上插入元素
bool CLinkList::insertnode(int value, int nPos)
{
if (nPos <= 0 || nPos > getcount() + 1)
{
return false;
}

PBINODE pNode = new LNode();
assert(pNode != NULL);
pNode->data = value;

PBINODE pPreNode = getnode(nPos - 1);
assert(pPreNode != NULL);

PBINODE ptmp = pPreNode->pnext;

pPreNode->pnext = pNode;
pNode->pnext = ptmp;

m_nCount++;

return true;
}

//
// 函数功能:删除第nPos位置上的元素
bool CLinkList::deletenode(int nPos)
{
if (nPos <= 0 || nPos > getcount())
{
return false;
}

PBINODE pNode = getnode(nPos - 1);
assert(pNode != NULL);
PBINODE pDNode = pNode->pnext;
assert(pDNode != NULL);
pNode->pnext = pDNode->pnext;

delete pDNode;
pDNode = NULL;

return true;
}

//
// 函数功能:打印链表
void CLinkList::printnode()
{
PBINODE root = getroot();
PBINODE pNode = root->pnext;
while(pNode != NULL)
{
cout<< pNode->data<< " ";
pNode = pNode->pnext;
}
cout<<endl;
}

//
// 函数功能:值为nValue元素的第n次出现的位置
int CLinkList::locate(int nvalue,int n)
{
PBINODE root = getroot();
PBINODE pNode = root->pnext;
int i = 0;

int nNum = 0;
while (pNode != NULL /*&& pNode->data != nvalue*/)
{
if (pNode->data == nvalue)
{
nNum++;
}
pNode = pNode->pnext;
i++;
if (nNum == n)
{
break;
}
}

if (pNode == NULL)
{
return 0;
}
else
{
return i;
}

}

//
// 函数功能:逆置
void CLinkList::reverse()
{
PBINODE root = getroot();
assert(root != NULL);

PBINODE prenode = root->pnext;
assert(prenode != NULL);

PBINODE curnode = prenode->pnext;
prenode->pnext = NULL;
while (curnode != NULL)
{
PBINODE nextnode = curnode->pnext;
curnode->pnext = prenode;
prenode = curnode;
curnode = nextnode;
}

root->pnext = prenode;
}

//
// 函数功能:排序(冒泡排序法)
void CLinkList::BubbleSort()
{
PBINODE root = getroot();
assert(root != NULL);

for (int i = 0; i < getcount(); i++)
{
PBINODE pNode = root->pnext;
for (int j = 0; j < getcount() - i; j++)
{
PBINODE pNodeNext = pNode->pnext;
if (pNodeNext == NULL)
{
break;
}
if (pNode->data > pNodeNext->data)
{
int tmp = pNode->data;
pNode->data = pNodeNext->data;
pNodeNext->data =  tmp;
}
pNode = pNode->pnext;
if (pNode == NULL)
{
break;
}
}
}
}

//已知指针la和lb分别指向两个链表。下列算法是从表la中删除自第i个元素起共len个元素后,将它们插入到表lb中第i个元素之前。
void DeleteAndInsertSub(CLinkList &la, CLinkList &lb, int i, int len)
{
if (i + len - 1 > la.getcount() || i <= 0 || len < 0 || i > lb.getcount())
{
return;
}

if (la.getroot() == lb.getroot())
{
return;
}

PBINODE pLa = la.getnode(i);
if (pLa == NULL)
{
return;
}

int nCount = 0;
while (nCount < len && pLa != NULL)
{
int nvalue = pLa->data;
lb.insertnode(nvalue, i + nCount);
pLa = pLa->pnext;
nCount++;
}
}

//已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序
void Merge(CLinkList &la, CLinkList &lb)
{

}

//如何检查一个单向链表上是否有环,同样两个指针,一个步长为1,另一个步长为2,如果两个指针能相遇则有环。
bool IsCircle(const CLinkList &la)
{

}

//只给定单链表中某个结点p(并非最后一个结点,即p->next!=NULL)指针,删除该结点。将p后面那个节点的值复制到p,删除p后面的节点
void DeleteNode(int nPos)
{

}

//在p前面插入一个节点 。在p后面插入新节点,将p的值与新建的节点值互换。
void InsertNode(int nPos)
{

}

//给定单链表头结点,删除链表中倒数第k个结点. 一个指针指向链表头,另一个指针指向第k个指针,然后两个指针一起移动,第二个指针到了末端则第一个指针就是倒数第k个节点
void ReverseDelete(int npos)
{

}

//判断两个链表是否相交。两种情况,如果链表有环,则先在环里设定一个指针不动,另一个链表从头开始移动,如果另一个链表能够与环中的指针相遇则是相交。如果没有环,则判断两个链表的最后个节点是否相同,相同则相交
bool IsCross(const CLinkList &la, const CLinkList &lb)
{

}

//两个链表相交,找出交点求出两个链表的长度a和b,一个指针指向较短链表的头head,另一个指针指向较长链表的第head+|a-b|,然后两个指针一起移动,相遇处即为交点。
int CrossNode(const CLinkList &la, const CLinkList &lb)
{

}

int _tmain(int argc, _TCHAR* argv[])
{
CLinkList link1;

cout<<"初始化链表link1:"<<endl;
int i = 0;
for (i = 1; i <= 15; i++)
{
int val = random(100);
if (!link1.insertnode(val, i))
{
return 0;
}
}

link1.insertnode(41, 10);
link1.printnode();
cout<<"link1链表长度为:"<<link1.getcount()<<endl;
cout << "41在link1中第2次出现的位置:"<<link1.locate(41, 2)<<endl;
cout<<"link1链表逆序为:"<<endl;
link1.reverse();
link1.printnode();
cout<<endl;

CLinkList link2;
cout<<"初始化链表link2:"<<endl;
for (i = 1; i <= 20; i++)
{
int val = random(100);
if (!link2.insertnode(val, i))
{
return 0;
}
}
link2.insertnode(41, 17);
link2.printnode();
cout<<"link2链表长度为:"<<link2.getcount()<<endl;

DeleteAndInsertSub(link1, link2, 3, 3);
link2.printnode();
cout<<"修改后link2链表长度为:"<<link2.getcount()<<endl;

cout<<endl<<"两个链表进行排序,排序后显示:"<<endl;
link1.BubbleSort();
link1.printnode();

link2.BubbleSort();
link2.printnode();

cout<<"获取link1的中间元素:";
cout<<link1.getmid()<<endl;
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: