10单链表操作
Posted 樱桃挚爱丸子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10单链表操作相关的知识,希望对你有一定的参考价值。
单链表操作
单链表操作1
/*单链表的类型定义*/ typedef int DataType; typedef struct node { DataType data; struct node * next; }LinkNode, *LinkList; /*单链表的定位运算*/ LinkNode *Locate(LinkNode *L, int k)//????为什么此处是LinkNode *Locate()类型,表示什么意思 { LinkNode *p; int i; i= 1; p = L->next; //初始时p指向第一个元素结点,i为计数器 while(p != NULL && i < k ) //通过链接指针逐个向后查找第k个结点 { p = p->next; i++; } if(p != NULL && i == k) //存在第k个元素且指针p指向该元素结点 return p; return NULL; //第k个元素不存在 }; /*单链表的插入运算*/ int Insert(LinkNode *L, int k, int elem) { LinkNode *p, *q; if(k==1) p=L; //元素elem插入在第1个元素位置 else p = Locate(L, k-1); //查找表中的第k-1个元素 if(p==NULL) return 0; //表中不存在第k-1个元素,插入失败 q = new LinkNode; //创建插入结点 if(q == NULL) { printf("存储分配失败!\n"); return 0; } q->data = elem; //元素elem插入第k-1个元素之后 q->next = p ->next; p->next = q; return 1; } /*单链表的删除运算*/ int Remove(LinkNode *l, int k) { linkNode *p, *q; if(k==1) p = L; //删除第一个元素结点 else p = Locate(L,k-1); //查找表中的第k-1个元素 if(p==NULL) //表中不存在第k-1个元素则删除失败 return 0; q = p->next; //令q指向第k个元素结点 p->next = q->next; delete q; //删除结点 return 1; }; /*在待头结点的单链表中寻找第i个结点*/ LinkNode *Locate(LinkList &L, int i) { if(i < 0) return NULL; //位置i在表中不存在 LinkNode *p = L; int k = 0; //从表头结点开始检测 while(p != NULL && k < i) //p=NULL表示链短,无第i个结点 { p = p -> next; k++; } return p; //否则k = i,返回第i个结点地址 }; /*在带头结点的单链表中确定值最大的结点*/ LinkNode *Max(LinkList &L) { if(L->next == NULL) return NULL; //空表,返回指针NULL LinkNode * pmax = L->next, p=L->next->next; //假定首元结点中的数据值最大 while(p != NULL) //循环,下一个结点存在 { if(p->data>pmax->data) //pmax记忆找到的具最大值的结点 pmax = p; p = p->next; //检测下一个结点 } return pmax; } /*统计带头结点的单链表中具有给定值x的所有元素*/ int Count(LinkList &L,DataType x) { int n = 0; LinkNode *p = L->next; //从首元结点开始检测 while(p != NULL) //循环,下一个结点存在 { if(p -> data == x) //找到一个,计数器加1 n++; p = p->next; //检测下一个结点 } return n; }; /*根据一维数组建立一个带头结点的单链表*/ void CreateList(LinkList &L, DataType A[], int n) { LinkNode *rear; L = rear = new LinkNode; //创建链表头结点 for(int i = 0; i<n; i++) { rear->next = new LinkNode; //链入一个新结点 rear = rear->next; //rear指向链中的尾结点 rear->data = A[i]; } rear->next = NULL; //链表收尾 }; /*在非递减有序的带头结点的单链表中删除值相同的多余结点*/ void tidyup(LinkLisy &L) //检测指针p指向首元结点 { LinkNode *p = L->next, temp; while(p != NULL && p ->next != NULL) //循环检测链表 if(p->data == p->next->data) //若相邻结点值相等 { temp = p->next; //从链表删除一个值相同的结点 p->next = temp->next; delete temp; //释放该结点 } else p = p->next; //指针p进到链表的下一个结点 }; /*递归实现求链表中的最大整数、表中结点的个数、所有元素的平均值*/ int Max(LinkNode *L) { if(L->link == NULL) //链表仅一个结点,其值即所求 return L->data; int (temp = Max(L->next)); //否则递归求后继结点中的最大值 if(L->data>temp) return L->data; //再与首元的值比较取大者 else return temp; }; int Num(LinkNode *L) { if(L==NULL) //空链表结点的个数为0 return 0; return 1+Num(L->next ); //否则求后继结点数再加1 }; float Avg(LinkNode *L, int &n) //链表仅一个结点 { if(L->next == NULL) //其值即所求 { n = 1; return(float)(L->data); } else //否则 { float Sum = Avg(L->next, n) * n; //先递归求后继结点的平均值 n++; //在计算总和 return (L->data+Sum)/n; //然后加上首元之值再求平均值 } }; /*通过遍历一趟链表,将链表中所有结点的链接方向逆转*/ void Reverse(LinkNode * &h) { if(h== NULL) return; LinkNode *p = h->next, *pr = NULL; //逆转h指针 while(p!=NULL) { h->next = pr; //指针前移 pr=h; h=p; p= p->next; } h->link = pr; }; void Reverse(LinkNode &L) { LinkNode *p =L->next, *pr ; L->link = NULL; while(p!=NULL) { pr = p; p = p->next; pr->next=L->next; //摘下剩余链首元结点 L->next = pr; //作为首元结点插入结果链 } }; /*在一个带头结点的单链表中所有元素的结点的数据按递增顺序排序,删除表中所有大于min且小于max的元素*/ typedef int DataType void rangeDelete(LinkNode &L, DataType min, DataType max) { LinkNode *pr = L, *p = L->next; while(p != NULL && p->data <= min) //寻找值大于min的元素 { pr = p; p = p-> next; } while(p != NULL && p->data < max) //删除值小于max的元素 { pr ->next = p->next; delete p; p = pr->next; } }; /*在一个带头结点的单链表中所有元素的结点的数据无序排序,删除表中所有大于min且小于max的元素*/ typedef int DataType void rangeDelete(LinkNode &L, DataType min, DataType max) { LinkNode *pr = L, *p = L->next; //p是检测指针,pr是其前驱 while(p != NULL) if(p ->data >min && p->data < max) //寻找到删除结点,删除 { pr ->next = p->next; delete p; p = pr->next; //否则继续寻找被删结点 } else { pr = p; p = p-> next; } };
单链表操作2
//指向结点的指针是结构体指针类型,链表是结构体指针类型???? #include<stdio.h> //带头结点的链表操作 #include<stdlib.h> #define ERROR 0 #define OK 1 #define OVERFLOW -1 typedef int ElemType; typedef struct LNode { ElemType data; struct LNode *next; //next指向了一个和它本身数据类型一样的下一个结点 }LNode,*LinkList; //LNode等价于struct LNode; LinkList等价于struct LNode * void GetElem(LinkList L,int i,ElemType *e) //查找第i个元素并返回,函数是无返回值类型 { LNode *p; //ElemType *e用于存储返回的值,LNode *p等价于LinkList p int j=1; p=L->next; //p=L->next,此时p指向首结点 while(p&&j<i) //如果结点为空就停止循环 { p=p->next;++j; } if(!p||j>i)printf("不存在,查找错误\n"); else *e=p->data; } void ListInsert_L(LinkList *L,int i,ElemType e)//插入元素。 { LinkList p=*L,s=NULL; //LinkList *L?????LinkList p=*L int j=0; while(p&&j<i-1){p=p->next;++j;} if(!p||j>i-1)printf("插入位置错误\n"); s=(LinkList)malloc(sizeof(LNode)); s->data=e; s->next=p->next; p->next=s; } void ListDelet_L(LinkList *L,int i,ElemType *e)//删除元素 { LNode *p=*L,*q=NULL; int j=0; while(p->next&&j<i-1) { p=p->next;++j; } if(!(p->next)||j>i-1)printf("删除位置错误"); q=p->next;p->next=q->next; *e=q->data; free(q); } void CreatList(LinkList *L,int n)//建立链表 输入n个ElemType类型的数 { LinkList p=NULL,q=NULL; int i; ElemType m; (*L)=(LinkList)malloc(sizeof(LNode)); (*L)->next=NULL; p=(LinkList)malloc(sizeof(LNode)); p->next=NULL; q=p; scanf("%d",&m); p->data=m; (*L)->next=p; for(i=1;i<n;i++) { p=(LinkList)malloc(sizeof(LNode)); scanf("%d",&m); p->data=m; q->next=p; p->next=NULL; q=p; } } void DisList(LinkList L) { LinkList p=L->next; while(p) { printf("%d ",p->data); p=p->next; } printf("\n"); } int main() { LinkList L=NULL; int i,p=1,m; ElemType e; printf("请输入10个元素:\n"); CreatList(&L,10); printf("原来的10个元素为:"); DisList(L); while(p) { printf("1)插入2)删除3)查找4)显示操作结果0)退出\n"); scanf("%d",&m); switch(m) { case 1:printf("请分别输入要插入元素的位置及与元素值: "); scanf("%d%d",&i,&e);ListInsert_L(&L,i,e);break; case 2:printf("请分别输入要删除元素的位置: "); scanf("%d",&i);ListDelet_L(&L,i,&e);printf("删除的元素值为:%d\n",e);break; case 3:printf("请分别输入要查找的元素的位置: "); scanf("%d",&i);GetElem(L,i,&e);printf("该位置的元素为:%d\n",e);break; case 4:DisList(L);break; case 0:p=0;break; } } return 0; }
单链表的插入3
#include"stdio.h" #include"malloc.h" #include"stdlib.h" /*尾插法建立链表,链表元素顺序和数组一致*/ LinkList CreatList2(LinkList &L) { //从表头到表尾正向建立单链表L,每次均在表尾插入元素 int x; // 设元素类型为整型 L=(LinkList)malloc(sizeof(LNode)); LNode *s, *r=L; //r 为表尾指针 scanf ("%d", &x); //输入结点的值 while (x!=9999) { //输入 9999 表示结束 s=(LNode *)malloc(sizeof(LNode)); s->data=x; r->next=s; r=s; //r指向新的表尾结点 scanf ("%d", &x); } r->next = NULL; //尾结点指针置空 return L; } /*头插法建立链表,链表元素顺序和数组相反*/ LinkList CreatList1(LinkList &L) { //从表尾到表头逆向建立单链表L,每次均在头结点之后插入元素 LNode *s;int x; L=(LinkList)malloc(sizeof(LNode)); //创建头结点 L->next=NULL; //初始为空链表 scanf("%d", &x); //输入结点的值 while(x!=9999) { //输入 9999 表示结束 s=(LNode*)malloc(sizeof(LNode) ); //创建新结点 s->data=x; s->next=L->next; L->next=s; //将新结点插入表中,L为头指针 scanf ("%d", &x); } //while 结束 return L; } int main (void) { return 0; }
单链表的操作4
/*The Data Structure of Link List*/ typedef int DataType; typedef struct LinkNode { DataType data; struct LinkNode *next; }*LinkList; /*尾插法建立链表,链表元素顺序和数组一致*/ void CreateList(LinkList &L,DataType A[],int n) { LinkNode *rear; L = rear = new LinkNode; for(int i=0; i<n; ++i) { rear->next = new LinkNode; rear = rear->next; rear->data = A[i]; } rear->next = NULL; } /*头插法建立链表,链表元素顺序和数组相反*/ void CreateList_reverse(LinkList &L,DataType A[], int n) { L = new LinkNode; L->next = NULL; for( int i=0; i<n; ++i) { LinkNode *p = new LinkNode; p->data = A[i]; p->next = L->next; L->next = p; } } /*链表逆置算法*/ void ReverseList(LinkList &L) { LinkNode *pre = NULL; /*two temporary node is needed to traverse the LinkList*/ LinkNode * p = L->next; while( p != NULL) { L->next = p->next; /* p->next will change,so store it in the head node*/ p->next = pre; pre = p; /* pre point to the new head */ p = L->next; /* p point to the next position */ } L->next = pre; /* L-next point to the head of the reversed list*/ } /*删除链表中的元素x*/ void DeleteList(LinkList &L,DataType x) { for(LinkNode *pre=L,*p=L->next; p!=NULL; pre=p,p=p->next ) if( p->data == x) { pre->next = p->next; delete p; return; } } /*插入链表元素x*/ void InsertList(LinkList &L ,DataType x) { LinkNode *p = new LinkNode; p->data = x; p->next = L->next; L->next = p; } /*显示链表所有元素,测试时比较有用*/ void DisplayList(LinkList &L) { cout<<endl; for( LinkNode *p = L->next; p != NULL; p = p->next ) { cout<< p->data<<" "; } cout<<endl; } *链表的排序算法*/ void InsertSortList(LinkList &L) { LinkNode *p = L->next; /*指向 待插入 结点 */ LinkNode *nextp = NULL; /*指向 p的后继 结点 */ LinkNode *q = L; /*指向有序链表的头部*/ q->next = NULL; while( p != NULL ) { q = L; while(q->next!=NULL && p->data >= q->next->data) /*寻找插入位置,循环停止时,p应插入到q的后面*/ { q = q->next; } nextp = p->next; p->next = q->next; /* p 的后继应是 q */ q->next = p; p = nextp; } } /*链表查找算法*/ LinkNode *SearchList(LinkList &L,DataType x) { LinkNode *p = L->next; while( p!=NULL && p->data!=x ) { p = p->next; } return p; } /*链表销毁算法*/ void DestroyList(LinkList &L) { if(L->next==NULL) { cout<<"delete"<<L->data<<endl; delete L; } else { DestroyList(L->next); cout<<"delete"<<L->data<<endl; delete L; } }
以上是关于10单链表操作的主要内容,如果未能解决你的问题,请参考以下文章