您的位置:首页 > 编程语言 > C语言/C++

链表操作集合 - C语言

2014-06-16 20:32 357 查看
主要是给自己以后复习知识,还有进行修改优化用的:

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

首先是头文件定义

#ifndef ANDREW
#define ANDREW

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <time.h>

#define SIZE 10

struct 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;

}
else
break;
}
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;
}
}


//删除无头单链表的一个节点q
Linklist 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;//返回新的头结点

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