【数据结构】链表

来源:互联网 发布:java lambda this 编辑:程序博客网 时间:2024/06/05 09:35

带头节点单链表

数据结构定义

ListNode.h#ifndef LISTNODE_H#define LISTNODE_Htemplate<class T> class ListNode{private:T data;ListNode<T> *next;public:ListNode();ListNode(T value);int Getdata();ListNode<T>* Getnext();void Setnext(ListNode<T>* p);};template<class T>ListNode<T>::ListNode():next(NULL){}template<class T> ListNode<T>::ListNode(T value):data(value),next(NULL){}template<class T> int ListNode<T>::Getdata(){return data;}template<class T> ListNode<T>* ListNode<T>::Getnext(){return next;}template<class T> void ListNode<T>::Setnext(ListNode<T>* p){next=p;}#endif
带头结点单链表的所有操作实现

LinkList.h#include<iostream>#include "ListNode.h"using namespace std;template<class T>class LinkList{private:ListNode<T> *head;ListNode<T> *tail;public:LinkList();bool IsEmpty();int ListLength();//不包括头结点void AddHead(T value);void AddTail(T value);//从第0个位置开始,第0个元素是除过头结点的节点T GetAtIndex(int index);bool InsertAt(int index,T value);bool RemoveAt(int index,T &value);bool RemoveAtPtr(ListNode<T>* del);ListNode<T>* GetHead();ListNode<T>* GetTail();ListNode<T>* GetNodePtr(int index);void DestroyList();void TraverseList();};template<class T> LinkList<T>::LinkList(){head=new ListNode<T>;tail=head;}template<class T> bool LinkList<T>::IsEmpty(){if (head->Getnext()==NULL)return 1;return 0;}template<class T> int LinkList<T>::ListLength(){int len=0;ListNode<T>*p=head->Getnext();while (p){len++;p=p->Getnext();}return len;}template<class T> void LinkList<T>::AddHead(T value){ListNode<T>* p=new ListNode<T>(value);p->Setnext(head->Getnext());head->Setnext(p);}template<class T> void LinkList<T>::AddTail(T value){ListNode<T>* p=new ListNode<T>(value);tail->Setnext(p);tail=tail->Getnext();}template<class T> T LinkList<T>::GetAtIndex(int index){if(index>ListLength()||index<0){cout<<"选择位置不正确!\n";return -1;//出错}int i=0;ListNode<T>* p=head->Getnext();while (i<index){p=p->Getnext();//跳出的时候P指向index节点i++;}return p->Getdata();}template<class T> bool LinkList<T>::InsertAt(int index,T value){if(index>ListLength()||index<0){cout<<"插入位置不正确!\n";return 0;//出错}int i=-1;ListNode<T>* p=head;ListNode<T>* add=new ListNode<T>(value);while (i<index-1){p=p->Getnext();//跳出的时候P指向index的前一个节点i++;}add->Setnext(p->Getnext());p->Setnext(add);return 1;}template<class T> bool LinkList<T>::RemoveAt(int index,T &value){if(index>ListLength()||index<0){cout<<"删除位置不正确!\n";return 0;//出错}int i=-1;ListNode<T>* p=head;while (i<index-1){p=p->Getnext();//跳出的时候P指向index的前一个节点i++;}ListNode<T>* del=p->Getnext();p->Setnext(del->Getnext());value=del->Getdata();delete del;return 1;}template<class T> bool LinkList<T>::RemoveAtPtr(ListNode<T>*del){ListNode<T>* p=GetHead();while(p->Getnext()!=del)p=p->Getnext();//跳出时p->next==del;ListNode<T>* ptrdel=p->Getnext();p->Setnext(ptrdel->Getnext());delete ptrdel;return 1;}template<class T> ListNode<T>* LinkList<T>::GetHead(){return head;}template<class T> ListNode<T>* LinkList<T>::GetTail(){return tail;}template<class T> ListNode<T>* LinkList<T>::GetNodePtr(int index){ListNode<T>* p=head->Getnext();int i=0;while (i<index){p=p->Setnext(p);i++;}return p;}template<class T> void LinkList<T>::DestroyList(){while (head->Getnext()){ListNode<T> * del=head->Getnext();head->Setnext(del->Getnext());delete del;}}template<class T> void LinkList<T>::TraverseList(){if (IsEmpty())cout<<"链表为空";ListNode<T>*p=head->Getnext();while (p){cout<<p->Getdata()<<endl;p=p->Getnext();}}测试:#include "LinkList.h"#include "ListNode.h"#include <iostream>using namespace std;void main(){LinkList<int> myList1;LinkList<int> myList2;myList1.AddTail(2);myList1.AddTail(4);myList1.AddTail(6);myList1.AddTail(8);myList1.AddTail(10);myList1.RemoveAtPtr(myList1.GetHead()->Getnext());cout<<"myList1元素:\n";myList1.TraverseList();myList2.AddTail(3);myList2.AddTail(3);myList2.AddTail(5);myList2.AddTail(7);myList2.AddTail(12);cout<<"myList2元素:\n";myList2.TraverseList();cout<<"合并后的链表元素:\n";int pos=0;ListNode<int>* p=myList2.GetHead()->Getnext();while (p&&pos<myList1.ListLength()){if (p->Getdata()<myList1.GetAtIndex(pos)){myList1.InsertAt(pos,p->Getdata());//ListNode<int> *del=p;p=p->Getnext();//myList2.RemoveAtPtr(del);//删除指针对应的节点int s;myList2.RemoveAt(0,s);//删除首节点 也就是删除第0个元素}pos++;}if (p){myList1.GetTail()->Setnext(p);}myList1.TraverseList();getchar();}
不带头结点单链表
不带头结点单链表/************************************************************************//* 无头结点链表的创建                                               *//************************************************************************/#include <iostream.h>typedef struct node{int data;struct node *next;}Node,*LinkList;LinkList CreateListHead();//头插创建链表LinkList CreateListRear();//尾插创建链表void TraverseList(LinkList L);//遍历链表bool IsEmpty(LinkList L);//判断是否为空int ListLength(LinkList L);//链表长度bool GetElem(LinkList L,int i,int &e);//获取第i个元素给ebool InsertElem(LinkList &L,int i,int e);//第i个位置插入元素ebool DeleteIndexElem(LinkList &L,int i);//第i个位置插入元素ebool DeletePointElem(LinkList &L,LinkList del);//第i个位置插入元素ebool DestroyList(LinkList &L);//销毁链表/*头插法*/LinkList CreateListHead(){LinkList head=NULL;for (int i=1;i<42;i++){LinkList p=new Node;p->data=i;p->next=head;head=p;}return head;}/*尾插法*/LinkList CreateListRear(){LinkList head=NULL;LinkList tail=head;for (int i=1;i<42;i++){LinkList p=new Node;p->data=i;p->next=NULL;if (i==1){head=p;tail=head;}else{tail->next=p;tail=p;}}return head;}void TraverseList(LinkList L){LinkList p=L;cout<<"链表元素为:"<<endl;while (p){cout<<p->data<<" ";p=p->next;}cout<<endl;}bool IsEmpty(LinkList L){if(L=NULL)return 1;return 0;}int ListLength(LinkList L){int i=0;LinkList p=L;while (p){i++;p=p->next;}return i;}bool GetElem(LinkList L,int i,int &e){int j=1;LinkList p=L;if (i<1||i>ListLength(L))return false;while (j<i){p=p->next;j++;}e=p->data;return 1;}bool InsertElem(LinkList &L,int i,int e){LinkList p=L;int j=1;LinkList temp=new Node;if (i<1||i>ListLength(L))return 0;else if (1==i){temp->data=e;temp->next=L;L=temp;}else{while (j<i-1){p=p->next;j++;}temp->data=e;temp->next=p->next;p->next=temp;}return 1;}bool DeleteIndexElem(LinkList& L,int i){LinkList p=L;int j=1;if (i<1||i>ListLength(L))return 0;else if (1==i){L=L->next;delete(p);}else{while (j<i-1){p=p->next;j++;}LinkList temp=p->next;p->next=p->next->next;delete(temp);}return 1;}bool DeletePointElem(LinkList &L,LinkList del){LinkList p=L;if (del==L){L=L->next;delete p;}else{while (p->next!=del)p=p->next;p->next=del->next;delete del;}return 1;}bool DestroyList(LinkList &L){LinkList p=L;while (L){p=L;L=L->next;delete(p);}return 1;}// 测试void main(){//int e;LinkList List=CreateListRear();TraverseList(List);//GetElem(List,5,e);//cout<<e<<endl;//DeleteIndexElem(List,1);//DeletePointElem(List,List->next);//TraverseList(List);}

带头节点的循环链表

/************************************************************************//* 带头结点的循环链表的创建*//************************************************************************/#include <iostream.h>typedef struct node{int data;struct node *next;}Node,*LinkList;LinkList CreateListHead();//头插创建链表LinkList CreateListRear();//尾插创建链表void TraverseList(LinkList L);//遍历链表bool IsEmpty(LinkList L);//判断是否为空int ListLength(LinkList L);//链表长度bool GetElem(LinkList L,int i,int &e);//获取第i个元素给ebool InsertElem(LinkList L,int i,int e);//第i个位置插入元素ebool DeleteIndexElem(LinkList L,int i);//删除第i个位置的元素bool DeletePointElem(LinkList L,LinkList del);//删除给定指针对应的元素第void main(){//int e;LinkList List=CreateListRear();TraverseList(List);//cout<<IsEmpty(List);//cout<<ListLength(List);//GetElem(List,44,e);//cout<<e;//InsertElem(List,41,100);//TraverseList(List);//DeleteIndexElem(List,1);//TraverseList(List);//DeleteIndexElem(List,40);//TraverseList(List);//DeletePointElem(List,List->next);//TraverseList(List);}/*头插法*/LinkList CreateListHead(){LinkList head=new Node;head->next=head;for (int i=1;i<42;i++){LinkList p=new Node;p->data=i;p->next=head->next;head->next=p;}return head;}/*尾插法*/LinkList CreateListRear(){LinkList head=new Node;head->next=head;LinkList tail=head;for (int i=1;i<42;i++){LinkList p=new Node;p->data=i;p->next=head;tail->next=p;tail=p;}return head;}void TraverseList(LinkList L){LinkList p=L->next;cout<<"链表元素为:"<<endl;while (p!=L){cout<<p->data<<" ";p=p->next;}cout<<endl;}bool IsEmpty(LinkList L){if(L->next==L)return 1;return 0;}int ListLength(LinkList L){int i=0;LinkList p=L->next;while (p!=L){i++;p=p->next;}return i;}bool GetElem(LinkList L,int i,int &e){int j=0;LinkList p=L;if (i<1||i>ListLength(L))return 0;while (j<i){p=p->next;j++;}e=p->data;return 1;}bool InsertElem(LinkList L,int i,int e){LinkList p=L;int j=0;LinkList temp=new Node;if (i<1||i>ListLength(L))return 0;while (j<i-1){p=p->next;j++;}temp->data=e;temp->next=p->next;p->next=temp;return 1;}bool DeleteIndexElem(LinkList L,int i){LinkList p=L;int j=0;if (i<1||i>ListLength(L))return 0;while (j<i-1){p=p->next;j++;}LinkList temp=p->next;p->next=p->next->next;delete(temp);return 1;}bool DeletePointElem(LinkList L,LinkList del){LinkList p=L;while (p->next!=del)p=p->next;p->next=del->next;delete del;return 1;}
不带头结点的循环链表

/************************************************************************//* 不带头结点的循环链表                                               *//************************************************************************/#include <iostream.h>typedef struct node{int data;struct node *next;}Node,*LinkList;LinkList CreateListHead();//头插创建链表LinkList CreateListRear();//尾插创建链表void TraverseList(LinkList L);//遍历链表//bool IsEmpty(LinkList L);//判断是否为空//int ListLength(LinkList L);//链表长度//bool GetElem(LinkList L,int i,int &e);//获取第i个元素给e// bool InsertElem(LinkList L,int i,int e);//第i个位置插入元素ebool DeleteIndexElem(LinkList L,int i);//删除第i个位置的元素bool DeletePointElem(LinkList &L,LinkList del);//删除给定指针对应的元素第void Josephus(LinkList L);// 测试void main(){//int e;LinkList List=CreateListRear();TraverseList(List);//DeletePointElem(List,List);Josephus(List);}/*头插法*/// LinkList CreateListHead()// {// LinkList head=NULL;// for (int i=41;i>0;i--)// {// LinkList p=new Node;// p->data=i;// p->next=head;// head=p;// }// return head;// }/*尾插法*/LinkList CreateListRear(){LinkList head=NULL;LinkList tail=head;for (int i=1;i<42;i++){LinkList p=new Node;p->data=i;p->next=head;if (i==1){head=p;tail=head;}else{tail->next=p;tail=p;}}return head;}void TraverseList(LinkList L){LinkList p=L;cout<<"链表元素为:"<<endl;while (p->next!=L){cout<<p->data<<" ";p=p->next;}cout<<p->data;cout<<endl;}// bool IsEmpty(LinkList L)// {// if(L->next==L)// return 1;// return 0;// }// int ListLength(LinkList L)// {// int i=0;// LinkList p=L->next;// while (p!=L)// {// i++;// p=p->next;// }// return i;// }// bool GetElem(LinkList L,int i,int &e)// {// int j=0;// LinkList p=L;// if (i<1||i>ListLength(L))// return 0;// while (j<i)// {// p=p->next;// j++;// }// e=p->data;// return 1;// }// bool InsertElem(LinkList L,int i,int e)// {// LinkList p=L;// int j=0;// LinkList temp=new Node;// if (i<1||i>ListLength(L))// return 0;// while (j<i-1)// {// p=p->next;// j++;// }// temp->data=e;// temp->next=p->next;// p->next=temp;// return 1;// }// bool DeleteIndexElem(LinkList L,int i)// {// LinkList p=L;// int j=0;// if (i<1||i>ListLength(L))// return 0;// while (j<i-1)// {// p=p->next;// j++;// }// LinkList temp=p->next;// p->next=p->next->next;// delete(temp);// return 1;// }bool DeletePointElem(LinkList &L,LinkList del){LinkList p=L;if (del==L){while (p->next!=del)p=p->next;L=L->next;p->next=L;delete del;}else{while (p->next!=del)p=p->next;p->next=del->next;delete del;}return 1;}// 约瑟夫问题的解决方法void Josephus(LinkList L){LinkList p=L;while (L){cout<<p->next->next->data<<endl;DeletePointElem(L,p->next->next);p=p->next->next;if(p->next==p)break;}}

双向链表

#include<stdio.h>#include<malloc.h>typedef struct node {int data;struct node *prior;struct node *next;}DNode,*DLinkList;DLinkList CreateDList();void TraverseList(DLinkList L);bool IsEmpty(DLinkList L);int  Length(DLinkList L);DLinkList GetElem(DLinkList L,int i);bool InsertElem(DLinkList L,int i,int e);bool DeleteElem(DLinkList L,int i,int &e);void main(){DLinkList Dlist=CreateDList();printf("list的元素:\n");TraverseList(Dlist);InsertElem(Dlist,3,3);printf("插入元素后的list:\n");TraverseList(Dlist);}DLinkList CreateDList(){//尾插法DLinkList head=(DLinkList)malloc(sizeof(DNode));DLinkList tail;head->next=head->prior=NULL;//建立一个带头结点的空表tail=head;for (int i=0;i<4;i++){DLinkList p=(DLinkList)malloc(sizeof(DNode));scanf("%d",&p->data);p->next=NULL;p->prior=tail;tail->next=p;tail=p;}return head;}bool IsEmpty(DLinkList L){if (L->next==NULL)return 1;return 0;}void TraverseList(DLinkList L){if (!IsEmpty(L)){DLinkList p=L->next;while (p!=NULL){printf("%d\n",p->data);p=p->next;}}}int  Length(DLinkList L){int len=0;if (!IsEmpty(L)){DLinkList p=L->next;while (p!=NULL){len++;p=p->next;}}return len;}DLinkList GetElem(DLinkList L,int i){DLinkList p=L->next;int j=1;if(i<1||i>Length(L)){return 0;}while (j<i){p=p->next;j++;}return p;}bool InsertElem(DLinkList L,int i,int e){DLinkList p;if(!(p=GetElem(L,i-1)))return 0;DLinkList s=(DLinkList)malloc(sizeof(DNode));s->data=e;s->next=p->next;p->next->prior=s;p->next=s;s->prior=p;return 1;}

经典面试题:快慢指针实现快速找到链表的中间元素(带头结点单链表)

#include<stdio.h>#include<malloc.h>typedef struct node {int data;struct node *next;}Node,*LinkList;LinkList CreateDList();void TraverseList(LinkList L);bool IsEmpty(LinkList L);int  Length(LinkList L);LinkList GetElem(LinkList L,int i);bool InsertElem(LinkList L,int i,int e);//bool DeleteElem(LinkList L,int i,int &e);int MidElem(LinkList L);//返回中间元素void main(){LinkList list=CreateDList();printf("list的元素:\n");TraverseList(list);//InsertElem(list,3,3);//printf("插入元素后的list:\n");//TraverseList(list);printf("中间的元素为:%d\n",MidElem(list));}LinkList CreateDList(){//尾插法LinkList head=(LinkList)malloc(sizeof(Node));LinkList tail;head->next=NULL;//建立一个带头结点的空表tail=head;for (int i=0;i<3;i++){LinkList p=(LinkList)malloc(sizeof(Node));scanf("%d",&p->data);p->next=NULL;tail->next=p;tail=p;}return head;}bool IsEmpty(LinkList L){if (L->next==NULL)return 1;return 0;}void TraverseList(LinkList L){if (!IsEmpty(L)){LinkList p=L->next;while (p!=NULL){printf("%d\n",p->data);p=p->next;}}}int  Length(LinkList L){int len=0;if (!IsEmpty(L)){LinkList p=L->next;while (p!=NULL){len++;p=p->next;}}return len;}LinkList GetElem(LinkList L,int i){LinkList p=L->next;int j=1;if(i<1||i>Length(L)){return 0;}while (j<i){p=p->next;j++;}return p;}bool InsertElem(LinkList L,int i,int e){LinkList p;if(!(p=GetElem(L,i-1)))return 0;LinkList s=(LinkList)malloc(sizeof(Node));s->data=e;s->next=p->next;p->next=s;return 1;}//快慢指针实现快速找到链表的中间元素int MidElem(LinkList L){LinkList p;LinkList mid;p=mid=L;//P必须指向头结点这样才能保证链表在不为空的下限时p->next->next是正确的语句if (p->next==NULL)return 0;//空链表while(1){if (p==NULL||p->next==NULL)//p为NULL时是奇数个数字的情况p->next==NULL是偶数个的情况return mid->data;else{p=p->next->next;mid=mid->next;}}}





2 0