链表操作集合 - C语言

来源:互联网 发布:网络关注提款风控 编辑:程序博客网 时间:2024/05/17 01:34

主要是给自己以后复习知识,还有进行修改优化用的:

欢迎批评,其中链表合并的就地合并我并未掌握,我用了新的头结点以后要补上

首先是头文件定义

#ifndef ANDREW#define ANDREW#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include <time.h>#define SIZE 10struct Lnode;typedef int Elemtype;typedef struct Lnode{Elemtype data;struct Lnode *next;  //定义一个struct Lnode 类型的指针}Lnode,*Linklist; //一个普通类型 一个指针类型void create_and_insert1(Linklist *pList);//不带头的尾插void create_and_insert2(Linklist *head); //不带头的头插void create_and_insert_sort();        //不带头的顺序插void Showlinklist(Lnode *head);     //打印链表void create_sort_insert(Linklist* pList) ;void Shownodelinklist(Lnode *head);    //打印带头结点的链表Linklist Makeempty();  //初始化Linklist Makelinklistlast(Linklist head,int n); //尾插Linklist Makelinklistfront(Linklist head,int n);  //头插Lnode *Islast(Lnode *head);Lnode *Find(Linklist L,Elemtype key);Lnode *Delete(Linklist L,Elemtype key);   //删除所有为key的结点Lnode *Findprevious(Linklist L,Elemtype key);   //找到key结点的前驱Linklist Elemfour(Linklist head,int k);Linklist Middlenode(Linklist head);Linklist Nizhilinklist(Linklist head); //链表逆置  带头结点Linklist Sortlinklist(Linklist head);     //**************************************Linklist Deleteallelement(Linklist head);#endif 

#include "superman.h"//无头结点尾插void create_and_insert1(Linklist *pList){int number;Linklist Tail = *pList =(Linklist)calloc(1,sizeof(Lnode)); //第一个结点已经初始化int count=0;//srand(time(NULL));for(;count!=SIZE;count++){if(count==0){(*pList) -> data =rand()%100;}else{           //动态分配 不会自动释放,Linklist pcur=(Linklist)calloc(1,sizeof(Lnode));   //已初始化完成// printf("the %dst number:\n",count);// scanf("%d",&number);pcur->data=rand()%100;Tail->next=pcur;Tail=pcur;}}}

//无头结点头插void create_and_insert2(Linklist *head) //我理解head是一个指向结构体的指针{Lnode *Tail=*head=(Lnode*)calloc(1,sizeof(Lnode));int count=0;//srand(time(NULL));for(;count!=SIZE;++count){if(count==0){(*head) -> data =rand()%100;}else{Lnode *p=(Lnode*)calloc(1,sizeof(Lnode));p->data=rand()%100;p->next= *head;         //head本身是结构体的地址*head=p;}}}

//顺序插入void create_and_insert_sort(Linklist *head)    //用两个指针  一个标记前驱{   Linklist pre,last;int count=0;srand(time(NULL));*head =(Lnode*)calloc(1,sizeof(Lnode)); for(;count!=SIZE;++count){if(count==0){(*head)->data =rand()%100;}else{Lnode *p=(Lnode *)calloc(1,sizeof(Lnode));  //新插入的结点p-> data=rand()%100;pre=NULL;last=*head;while(last)  //定位要插入的位置{if(p->data>=last->data){pre=last;last=last->next;}elsebreak;}if(pre==NULL)    // 判断是否在首部插入。插入首部之前{p->next=*head;*head=p;}else{p->next = pre->next;pre->next= p;}}}}

//打印链表void Showlinklist(Lnode *head){Lnode *p=head;while(p!=NULL){printf("%d ",p->data);p=p->next;}printf("\n");}

//打印带头结点的void Shownodelinklist(Lnode *head){Lnode *p=head->next;while(p!=NULL){printf("%d ",p->data);p=p->next;}printf("\n");}

Linklist Makeempty(){Lnode *head=(Lnode *)malloc(sizeof(Lnode));if(!head){printf("Error!\n");}head->data=SIZE;head->next=NULL;return head;}

//带头结点的尾插法 Linklist Makelinklistlast(Linklist head,int n)   //没有返回值的时候 应该用两个解引用{int i;int number;Lnode *last=head; //不存储数据的只是指针不用开辟空间,但是存储数据的需要开辟空间。for(i=0;i<n;++i){Lnode *p=(Lnode *)malloc(sizeof(Lnode));// printf("the %d st number:\n",i+1);// fflush(stdin);// scanf("%d",&number);p->data=rand()%100;                     //number;last->next=p;last=p;}last->next=NULL;return head;}

//带头结点头插法Linklist Makelinklistfront(Linklist head,int n){int i;int number;Lnode *front=head;for(i=0;i<n;++i){Lnode *p=(Lnode *)calloc(1,sizeof(Lnode));// printf("the %d st number :\n",i+1);// scanf("%d",&number);p->data=rand()%100;                         // number;p->next=front->next;front->next=p;}return head;}

//返回最后一个结点Lnode *Islast(Lnode *head){Lnode *p=head;while(p->next!=NULL){p=p->next;}return p;}

//查找某个节点Lnode *Find(Linklist L,Elemtype key){Lnode *p=L->next;while(p->next!=NULL && p->data !=key){p=p->next;}return p;}

//删除所有值为KEY的结点Lnode *Delete(Linklist L,Elemtype key){Lnode *pre=L;           //循环查找,对头和尾特殊处理Lnode *last=pre->next;while(last){if(last->data==key){pre->next=last->next;free(last);last=pre->next;}else{pre=last;last=last->next;}}return L;}

//寻找前驱Lnode *Findprevious(Linklist L,Elemtype key){Lnode *p=L;   //从第一个节点开始查找while(p->next!=NULL && p->next->data !=key)   //思考是p->next还是判断p!=NULL{p=p->next;}return p;}

//寻找倒数第K个结点 Linklist Elemfour(Linklist head,int k){int i;Linklist quick,slow;quick=slow=head->next;     //判断单链表的长度for(i=0;i<k;++i){if(quick->next==NULL){printf("Error!\n");break;}quick=quick->next;}while(quick->next!=NULL){quick=quick->next;slow=slow->next;}return slow;}

//找出单链表的中间元素Linklist Middlenode(Linklist head){int i=0;Linklist quick,slow,longlist;longlist=head;quick=slow=head->next;while(longlist!=NULL){longlist=longlist->next;i++;}if(i%2==0){while(quick->next->next!=NULL){quick=quick->next->next;slow=slow->next;}}else{while(quick->next=NULL){quick=quick->next->next;slow=slow->next;}}

//删除无头单链表的一个节点qLinklist Deletenode(Linklist q){Elemtype temp;Linklist last;last=q->next;temp=q->data;q->data=last->data;last->data=temp;q->next=q->next->next;return q;}

//单链表逆置Linklist Nizhilinklist(Linklist head){Linklist pre,mid,last;pre=head->next;while(pre->next!=NULL){mid=pre->next;last=pre->next->next;mid->next=head->next;head->next=mid;pre->next=last;}return head;}

//链表合并(新建一个头结点)Linklist Mergelinklist(Linklist head1,Linklist head2){Linklist pre1,pre2,tail;Lnode *head;tail=(Lnode *)calloc(1,sizeof(Lnode));head=tail;pre2=head2;pre1=head1;while(pre1  &&  pre2){if(pre1->data<pre2->data){tail->next=pre1;tail=pre1;pre1=pre1->next;}else{tail->next=pre2;tail=pre2;pre2=pre2->next;} }if(pre1){tail->next=pre1;}else if(pre2){tail->next=pre2;}return head;}

//判断单链表是否有环? void Circlelinklist(Linklist head) { Linklist quick,slow; slow=quick=head->next; while(quick && quick->next!=NULL)   //可以quick走到链表的终点 { quick=quick->next->next; slow=slow->next; if(quick==slow) { printf("it has circle ! \n"); break; }  }  }

//判断两个单链表是否相交 void Intersectlinklist(Linklist head1,Linklist head2) { int i,j; Linklist first,second; int dis; i=j=0; first=head1->next; second=head2->next; while(first) { first=first->next; ++i; } first=head1; while(second) { second=second->next; ++j; } second=head2; if(i>j) { dis=i-j;while(dis){first=first->next;dis--;}while(first&&first->next!=NULL){first=first->next;second=second->next;if(first==second){printf("Intersect!!\n");break;}} } else if(i==j) { while(first&&first->next!=NULL) { first=first->next; second=second->next; if(first==second) { printf("Intersect!!\n"); break; } } } else { dis=j-i; while(dis) { second=second->next; dis--; } while(first&&first->next!=NULL) { first=first->next; second=second->next; if(first==second) { printf("Intersect!!\n"); break; } } } }

//单链表排序  插入排序 Linklist Sortlinklist(Linklist head) { //无头指针的排序 Linklist pre,pnext,mark,markbehind; mark=head->next; head->next=NULL;  //头部断开作为有序链 while(mark) { markbehind=mark->next;//标记操作结点的下一个位置 if(mark->data<=head->data)  //比头结点还小 插入头结点前面 { mark->next=head; head=mark; } else { pre=head;      //用于记录比较结点和结点的前驱 pnext=head->next; while(pnext&&pnext->data<mark->data)  //在有序链中找到合适的位置 { pre=pnext; pnext=pnext->next; } mark->next=pre->next; pre->next=mark; } mark=markbehind; } return head;//返回新的头结点  }


0 0