C语言版单链表史上最全功能.docx
《C语言版单链表史上最全功能.docx》由会员分享,可在线阅读,更多相关《C语言版单链表史上最全功能.docx(24页珍藏版)》请在冰豆网上搜索。
C语言版单链表史上最全功能
/*
****************************************************************************************************************************
*【1、程序功能:
实现单链表的14个功能】*
*【2、时间:
2016-08-05】*
*【3、欢迎指错:
273496225@】*
****************************************************************************************************************************
*/
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#defineOK0
#defineERROR-1
typedefintElemType;//数据域存放的元素
typedefstructNode
{
ElemTypeelement;//element:
元素
structNode*next;
}Node,*PNode;
voidinitList(PNode*pNode);/*1、函数功能:
初始化单链表*/
voidprintList(PNodepHead);/*2、函数功能:
打印单链表*/
PNodecreatList(PNode*pHead);/*3、函数功能:
创建单链表*/
intsizeList(PNodepHead);/*4、函数功能:
返回链表长度*/
intisEmptyList(PNodepHead);/*5、函数功能:
判断链表是否为空*/
intgetElement(PNodepHead,intpos);/*6、函数功能:
通过位置查找元素*/
intgetElemAddr(PNodepHead,ElemTypeelem);/*7、函数功能:
通过元素值返回元素位置*/
intmodifyElem(PNodepHead,intpos,ElemTypeposElem);/*8、函数功能:
修改指定位置上的元素值*/
PNodeinsertList(PNodepHead,intpos,ElemTypeelem);/*9、函数功能:
在指定位置上插入元素*/
intDelList(PNode*pHead,intpos);/*10、函数功能:
删除结点*/
intDelx(PNode*pHead,ElemTypeelem);/*11、函数功能:
删除第一个数据域为elem的结点,返回位置*/
intExchange2Pos(PNodepHead,intpos1,intpos2);/*12、函数功能:
交换两个位置上的元素的值*/
intArrange(PNodepHead);/*13、函数功能:
将单链表进行冒泡排序*/
intclearList(PNodepHead);/*14、函数功能:
清空链表*/
/*1、函数功能:
初始化单链表*/
voidinitList(PNode*pNode)
{
*pNode=NULL;
}
/*2、函数功能:
打印单链表*/
voidprintList(PNodepHead)
{
if(NULL==pHead)
{
printf("printList函数执行成功:
该链表是空链表!
\n");
}
else
{
for(;NULL!
=pHead;)
{
printf("%6d",pHead->element);
pHead=pHead->next;//两者都是指针,这样做不会改变主函数的pList
}
printf("\n");
}
}
/*原理:
1、首先判断链表是否为空,为空就退出;
2、否则就打印数据域,并且指针域依次后移,直到结构体等于NULL结束;
*/
/*3、函数功能:
创建单链表*/
PNodecreatList(PNodepHead)
{
PNodep1,p2;
p1=p2=(PNode)malloc(sizeof(Node));
if(NULL==p1||NULL==p2)
{
printf("内存分配失败!
\n");
exit(0);
}
memset(p1,0,sizeof(Node));//p1当前位置后面的sizeof(Node)个字节填充成0;清零作用
scanf("%d",&(p1->element));
p1->next=NULL;
for(;p1->element!
=-1;)
{
if(NULL==pHead)
{
pHead=p1;
}
else
{
p2->next=p1;//把p1接上来
}
p2=p1;//p2移动到末尾
p1=(PNode)malloc(sizeof(Node));
if(NULL==p1||NULL==p2)
{
printf("内存分配失败!
\n");
exit(0);
}
memset(p1,0,sizeof(Node));
scanf("%d",&(p1->element));//再读取数据
p1->next=NULL;//最后一个节点的next指向NULL
}
returnpHead;
}
/*原理:
1、参数传进来表头(pHead),然后定义两个结构体(p1、p2)指针,并申请空间;
2、给p1数据域赋值,指针域赋值为空;
3、进行循环,结束条件是数据域为-1;
4-1、第一次进去,让pHead指向p1,p2指向p1,p1重复申请赋值操作(步骤2);
4-2、第二次进去,因为上一次p2指向的p1,所以现在p2是链表的尾部,所以让p2->next指向p1,完成新节点的接入,
同样p2又指向p1,作为链表的尾部,p1再次申请重复步骤2;
5、最后返回pHead;
*/
/*4、函数功能:
返回链表长度*/
intsizeList(PNodepHead)
{
intsize=0;
for(;pHead!
=NULL;pHead=pHead->next,size++)
{
;
}
returnsize;
}
/*原理:
1、传进来头节点pHead,初始化长度size为0;
2、当pHead不为NULL,依次后移,size++;
3、返回size;
*/
/*5、函数功能:
判断链表是否为空*/
intisEmptyList(PNodepHead)
{
if(pHead!
=NULL)
{
returnOK;
}
else
{
returnERROR;
}
}
/*6、函数功能:
通过位置查找元素*/
intgetElement(PNodepHead,intpos)
{
/*排除超范围和空链表*/
if(pos<1||pos>sizeList(pHead))
{
printf("getElement函数执行成功,位置超出当前链表的范围(1-%d).\n",sizeList(pHead));
returnERROR;
}
intelem=0,postemp;
for(postemp=1;pos>=postemp;pHead=pHead->next,postemp++)
{
elem=pHead->element;
}
returnelem;
}
/*原理
1、判断输入的位置pos在不在1-链表长度之间,不在就结束;
2、循环,判断条件是位置>=当前位置,当前位置初始化为1,依次++;
3、元素elem等于当前结点的数据域
*/
/*7、函数功能:
通过元素值返回元素位置*/
intgetElemAddr(PNodepHead,ElemTypeelem)
{
inti;
if(pHead==NULL)
{
printf("链表为空!
!
\n");
returnERROR;
}
for(i=0;pHead!
=NULL;pHead=pHead->next,i++)
{
if(pHead->element==elem)
{
i++;
break;
}
}
if(pHead!
=NULL)
{
returni;
}
else
{
returnERROR;
}
}
/*8、函数功能:
修改指定位置上的元素值*/
intmodifyElem(PNodepHead,intpos,ElemTypeposElem)
{
inti;
if(pHead==NULL)
{
printf("错误:
链表为空,终止modifyElem函数。
\n",sizeList(pHead));
returnERROR;
}
if(pos<1||pos>sizeList(pHead))
{
printf("错误:
位置在1-%d,终止modifyElem函数。
\n",sizeList(pHead));
returnERROR;
}
for(i=1;pHead!
=NULL;pHead=pHead->next,i++)
{
if(i==pos)
{
pHead->element=posElem;
break;
}
}
returnOK;
}
/*9、函数功能:
在指定位置上插入元素*/
PNodeinsertList(PNodepHead,intpos,ElemTypeelem)
{
inti;
PNodeinsert,temp;
temp=pHead;
insert=(PNode)malloc(sizeof(Node));
insert->element=elem;
if(pos<1||pos>sizeList(pHead)+1)
{
printf("输入位置非法!
\n");
returnpHead;
}
if(pos==1)//头部
{
insert->next=temp;
pHead=insert;
}
elseif(pos==sizeList(pHead)+1)//尾部
{
for(;temp->next!
=NULL;temp=temp->next)
{
;
}
temp->next=insert;
insert->next=NULL;
}
else
{
for(i=1;i<=pos;i++,temp=temp->next)
{
if(pos-1==i)
{
insert->next=temp->next;
temp->next=insert;
}
}
}
returnpHead;
}
/*10、函数功能:
删除结点*/
intDelList(PNode*pHead,intpos)
{
ElemTypeelem;
PNodetemp;//不能定义成*temp,这样temp会直接改变链表在主函数的pList
temp=*pHead;
if(pHead==NULL)
{
printf("链表是空的!
\n");
returnERROR;
}
if(pos<1||pos>sizeList(*pHead))
{
printf("请输入1-%d之间的结点!
\n",sizeList(*pHead));
returnERROR;
}
if(pos==1)
{
elem=(*pHead)->element;
*pHead=(*pHead)->next;
}elseif(pos==sizeList(*pHead))
{
for(;(temp)->next->next!
=NULL;temp=(temp)->next)
{
;
}
elem=(temp)->next->element;
free((temp)->next);
(temp)->next=NULL;
}
else
{
for(inti=1;i!
=pos-1;(temp)=(temp)->next,i++)
{
;
}
elem=((temp)->next)->element;
(temp)->next=(temp)->next->next;
}
returnelem;
}
/*11、函数功能:
删除第一个数据域为elem的结点,返回位置*/
intDelx(PNode*pHead,ElemTypeelem)
{
PNodetemp,ptemp;
temp=*pHead;
inti,length;
length=sizeList(temp);
for(i=1;temp!
=NULL&&elem!
=temp->element;temp=temp->next,i++)//temp!
=NULL必须放在前面,因为为NULL的时候,就不存在element了
{
ptemp=temp;
}
if(temp!
=NULL&&i==1)
{
*pHead=(*pHead)->next;
}
elseif(temp==NULL)
{
printf("没有这个元素存在!
\n");
returnERROR;
}
elseif(temp!
=NULL&&i==length)
{
ptemp->next=NULL;
}
else
{
ptemp->next=ptemp->next->next;
}
returni;
}
/*原理:
1、计算出当前链表长度,定义两个接哦固体指针tmep、ptemp;
2、进行循环,循环体中的结构体指针比判断条件的结构体指针慢一次;
3、循环结束条件是temp=NULL时,表示这个元素不存在,注意两个条件的顺序;
4、进行判断,头节点,尾节点单独处理;
*/
/*12、函数功能:
交换两个位置上的元素的值*/
intExchange2Pos(PNodepHead,intpos1,intpos2)
{
PNodetemp1,temp2;
inti=0;
if(pHead==NULL)
{
printf("链表是空的!
\n");
returnERROR;
}
if(pos1<1||pos1>sizeList(pHead)||pos2<1||pos2>sizeList(pHead))
{
printf("位置介于1-%d之间\n",sizeList(pHead));
returnERROR;
}
for(i=1;pHead!
=NULL;i++,pHead=pHead->next)
{
if(i==pos1)
{
temp1=pHead;
}
if(i==pos2)
{
temp2=pHead;
}
}
ElemTypetemp;
temp=temp1->element;
temp1->element=temp2->element;
temp2->element=temp;
returnOK;
}
/*
原理:
1、判断位置pos是否合法
2、定义结构体指针,进行循环存pos1和pos2的结构体
3、交换这两个节点里面的元素值
*/
/*13、函数功能:
将单链表进行冒泡排序*/
intArrange(PNodepHead)
{
if(pHead==NULL)
{
printf("链表是空,没法排序!
\n");
returnERROR;
}
PNodetemp1,temp2;
intlength=sizeList(pHead);
inti,j;
ElemTypeetemp;
for(i=0;i{
temp1=pHead;
temp2=temp1->next;
for(j=i+1;j{
if(temp1->element>temp2->element)
{
etemp=temp1->element;
temp1->element=temp2->element;
temp2->element=etemp;
}
temp1=temp1->next;
temp2=temp2->next;
}
}
returnOK;
}
/*
原理:
1、进行判断
2、两个结构体指针temp1,temp2存放相差为1的结点
3、在两个for循环中,一前一后的结构体指针模拟数组相差为1的下标,注意每次外层for循环都让temp1,temp2回头
*/
/*14、函数功能:
清空链表*/
intclearList(PNodepHead)
{
PNodetemp;
if(pHead==NULL)
{
returnOK;
}
else
{
for(temp=pHead->next;temp!
=NULL;temp=temp->next)
{
free(pHead);
pHead=temp;
}
free(pHead);
}
returnOK;
}
/*
原理:
1、判断
2、一前一后free空间
*/
/*主函数*/
intmain()
{
PNodepList=NULL;
intpos;//位置
intlength=0;
ElemTypeposElem;//元素值
/*初始化*/
printf("开始初始化………\n");
initList(&pList);
printf("iniList函数执行,完成初始化成功!
\n");
printf("开始打印………\n");
printList(pList);
/*创建*/
printf("开始初创建【-1结束输入】………\n");
pList=creatList(pList);
printf("成功执行creatList函数,创建链表完成!
\n");
printf("开始打印链表………\n");
printList(pList);
printf("成功打印链表!
\n");
/*计算链表长度*/
printf("开始计算长度………\n");
printf("成功执行sizeList函数!
长度是%d.\n",sizeList(pList));
/*判断链表是否为空*/
printf("开始判断链表是否为空………\n");
if(isEmptyList(pList)==OK)
{
printf("执行isEmptyList成功,链表非空!
\n");
}
else
{
printf("执行isEmptyList成功,链表为空!
\n");
}
/*查找某个位置上的元素*/
printf("开始执行位置映射元素函数……\n");
printf("请输入位置:
");
scanf("%d",&pos);
posElem=getElement(pList,pos);
if(posElem!
=-1)
printf("getElement函数执行成功,%d位上的元素值是%d.\n",pos,posElem);
/*通过元素值返回元素位置*/
printf("开始执行元素映射位置函数……\n");
printf("请输入元素:
");
scanf("%d",&posElem);
pos=getElemAddr(pList,posElem);
if(pos==-1)
{
printf("getElemAddr函数执行成功,链表中不存在%d这个元素!
\n",posElem);
}
else
{
printf("getElemAddr函数执行成功,%d元素在链表的%d位!
\n",posElem,pos);
}
/*修改元素*/
printf("开始执行修改某位置上的元素函数……\n");
printf("请输入位置&元素:
");
scanf("%d%d",&pos,&posElem);
if(modifyElem(pList,pos,posElem)==OK)
{
printf("修改结果是:
\n");
printList(pList);
}
else
{
printf("修改失败!
\n");
}
/*插入元素*/
printf("开始执行插入元素函数……\n");
printf("请输入位置&元素