代码改变世界

链表

2012-07-28 11:42  javaspring  阅读(352)  评论(0编辑  收藏  举报

1、链表基本操作----(带头结点)链表创建、增加节点、删除节点、链表反转

// lb.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdlib.h"
#include <iostream>
#include <string>
using namespace std;

//定义链表的数据结构
template<class T>
struct List{
	T data;
	List *next;
};


//用数组创建一个带头节点单链表
template<class T>List<T>* createList(T *data,int n) 
{
	typedef List<T> *pList;   //实例化一个结构体模版,并定义它的别名

	pList pHead=(pList)malloc(sizeof(List<T>));
	pHead->next=NULL;

	pList p=pHead,pNew;
	for (int i=0;i<n;i++)
	{
		pNew=(pList)malloc(sizeof(List<T>));
		pNew->data=data[i];
		pNew->next=p->next;
		p->next=pNew;
		p=pNew;
	}

	return pHead;   //返回头节点
}

//打印链表的内容
template<class T>void printList(List<T> *l)
{
	if (l==NULL)   //链表为空,直接返回
	{
		return;
	}

	List<T> *pList=l->next;   
	while(pList!=NULL)
	{
		cout<<pList->data<<" ";
		pList=pList->next;
	}

	cout<<endl;
}

//释放链表内存,使用结构体指针的引用
template<class T>void freeList(List<T> *&l)  
{
	List<T> *pTemp;
	while(l!=NULL)
	{
		pTemp=l;
		l=l->next;
		free(pTemp);  //释放每个节点之后,注意置为NULL
		pTemp=NULL;
	}
}

//链表长度
template<class T>int lenList(List<T> *l)
{
	if (l==NULL)   //链表为空,直接返回0
	{
		return 0;
	}

	int len=0;
	List<T> *pList=l->next;
	while(pList!=NULL)
	{
		len++;
		pList=pList->next;
	}

	return len;
}

//在pos位置插入节点,使用结构体指针的引用
template<class T>void insertNode(List<T> *&l,int pos,int val)
{
	int len=lenList(l);
	if (pos<0||pos>len)   //插入位置不合法
	{
		cout<<"节点插入位置不正确,请重新插入!"<<endl;
		return;
	}

	List<T> *p=l,*pNew;

	for(int i=0;i<pos;i++)
		p=p->next;

	pNew=(List<T>*)malloc(sizeof(List<T>));  //插入节点
	pNew->data=val;
	pNew->next=p->next;
	p->next=pNew;
}

//返回在pos处的节点
template<class T>List<T> *getNode(List<T> *l,int pos)
{
	int len=lenList(l);

	if (pos<1||pos>len)  //该位置无节点
		return NULL;

	for (int i=0;i<pos;i++)
	{
		l=l->next;
	}

	return l;
}

//删除pos处节点,使用结构体指针的引用
template<class T>void deleteNode(List<T> *&l,int pos)
{
	int len=lenList(l);
	if (pos<1||pos>len)  //删除位置不合法
	{
		cout<<"节点删除位置不正确,请重新删除!"<<endl;
		return;
	}

	List<T> *p=l,*pTemp;

	for(int i=1;i<pos;i++)
		p=p->next;

	pTemp=p->next;    //删除节点
	p->next=pTemp->next;
	free(pTemp);
	pTemp=NULL;
}

//链表反转
template<class T>void reverseList(List<T> *&l)
{
	if (l==NULL)  //链表为空,直接返回
	{
		return;
	}

	typedef List<T> *pList;
	pList last,mid=NULL,p=l->next;

	while(p!=NULL)   //反转链表
	{
		last=mid;
		mid=p;
		p=p->next;
		mid->next=last;
	}

	l->next=mid;
}


//test链表
int main(int argc, char* argv[])
{
	int data[]={34,678,90,345,78,3546,980,5476,23,89,56879};
	int len=sizeof(data)/sizeof(int);

	List<int> *iList=createList(data,len);   //创建一个整型数据链表
	cout<<"原始链表:";
	printList(iList);
    
	cout<<"反转之后:";
	reverseList(iList);
	printList(iList);
	cout<<endl;

	for (int i=0;i<5;i++)
	{
		cout<<"在"<<i<<"位置插入"<<i<<"之后:";
		insertNode(iList,i,i);		
	    printList(iList);
	}
    cout<<endl;

    for (i=1;i<5;i++)
	{
		cout<<"在"<<i<<"位置删除之后:";
		deleteNode(iList,i);		
		printList(iList);
	}
	cout<<endl;

	cout<<"释放链表内存之后:";
	freeList(iList);
	printList(iList);
	cout<<endl;

	return 0;
}

2、链表高级操作

2-1、两个有序链表归并到其中一个链表中

pList mergeList(pList first,pList second)
{
	pList out,p1,p2,pLast;   //out为返回链表,p1指向first,p2指向second,pLast串联起两个链表
	
	//first链表为空
	if(first->next==NULL)             
		out=second;
		
	//second链表为空
	else if (second->next==NULL)
		out=first;
		
	//first和second都不为空
	else
	{
		p1=first->next;
		p2=second->next;
		
		//first链表为返回链表
		if (p1->data<=p2->data)
		{
			out=first;
			pLast=p1;            //pLast作用为串联这两个链表,指向返回链表的第一个节点
			p1=p1->next;
		} 
		
		//second链表为返回链表
		else
		{
			out=second;
			pLast=p2;
			p2=p2->next;
		}

		while(p1!=NULL&&p2!=NULL)
		{
			if (p1->data<=p2->data)
			{
				pLast->next=p1;  //pLast指向带返回的剩余节点
				pLast=p1;
				p1=p1->next;
			}
			else
			{
				pLast->next=p2;
				pLast=p2;
				p2=p2->next;
			}
		}

		if (p1!=NULL)
			pLast->next=p1;
		if(p2!=NULL)
			pLast->next=p2;
	}

	return out;
}