单链表的基本运算实现代码标注

来源:互联网 发布:程序员出书 编辑:程序博客网 时间:2024/05/07 13:54
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


typedef struct
{
char key[10];
char name[10];
int age;
}Data;                        //定义一个结构体 结构体名字为Data;
typedef struct Node               
{
Data nodeData;
struct Node *nextNode;    //struck Node *nextNode 表示这个类型的指针
}CLType;                      //定义链表结构  链表结构 名字为CLType




/*在尾部追加一个结点
首先创建一个新的结点
然后找到本来链表中最后一个结点
让最后一个结点指向刚刚新建的结点
最后让新建的结点指向的地址为空
*/
CLType * CLAddEnd(CLType *head,Data nodeData)                //追加结点
{
CLType *node,*htemp;         //node 为空结点的 指针
if(!(node=(CLType *)malloc(sizeof(CLType))))     //这里实际上就是创建了一个指针为node的结点,结点的数据区和指针区没有赋值
{
printf("申请内存失败\n");
return NULL;
}
else
{
node->nodeData=nodeData;      // 往空结点传入数据
node->nextNode=NULL;          //指针区 为空
if(head==NULL)                //如果头指针head为空的话 说明链表就一个头结点 
{
head = node;              //然后让 头指针指向node
return head;                
}
htemp = head ;
while(htemp->nextNode!=NULL)  //查找链表的末尾

htemp = htemp->nextNode;
}
htemp->nextNode=node;           //把新的结点插到尾部
return head;
}


}


/*在头部插入一个结点
首先创建一个新的结点 
然后让新的结点指向第二个结点,
再让头结点指向刚刚新建的结点
*/


CLType *CLAddFirst(CLType *head,Data nodeData)
{
CLType *node;
if(!(node=(CLType *)malloc(sizeof(CLType))))   //先执行malloc(****)开一个大小为CLType类型的空间
{
printf("申请内存失败\n");
return NULL;
}
else
{
node->nodeData = nodeData;  //保存数据
node->nextNode = head;      //指向头指针指向的结点
head = node;                //头指针指向新建的结点
return head;
}
}
/*
查找一个结点 并在查找的结点后面增加一个结点
首先 通过关键字找到所查找的结点
然后 新建一个结点,并指向所查找结点所指向的下一个结点
最后 查找的结点指向新建得的结点
*/


CLType *CLFindNode(CLType *head, char *key)//查找结点
{
   CLType *htemp;                          //先创建一个CLType类型的指针
   htemp = head;
   while(htemp)                            //当htemp不为空的时候
   {
   if(strcmp(htemp->nodeData.key,key)==0)
   {
   return htemp;
   }htemp = htemp->nextNode;
  
   }
   return NULL;
}




CLType *CLInsertNode(CLType *head, char *findkey,Data nodeData)
{
CLType *node,*nodetemp;   //这里的两个指针分别为 新建结点的 和 被查找的指针
if(!(node=(CLType *)malloc(sizeof(CLType))))
{
printf("申请内存失败!\n");
return NULL;
}
node->nodeData=nodeData;           
nodetemp=CLFindNode(head,findkey);  //用上一个函数
if(nodetemp)
{
node->nextNode=nodetemp->nextNode;//新的结点指向查找到结点的下一个节点
nodetemp->nextNode=node;          //查找的结点指向新建的结点
}
else
{
printf("未找到正确的插入位置!\n");
free (node);            //释放内存
}
return head;                //返回头指针
}


/* 删除某个结点
首先找到所要删除的结点
然后让其上一个结点指向下一个结点  (如何实现见下文标注)
最后用函数释放要删除的结点
*/


int CLDeleteNode(CLType *head,char *key)
{
CLType *node ,*htemp;    //htemp指针用来查找 node指针用来指向htemp
htemp=head;
node = head;
while(htemp)
{
if(strcmp(htemp->nodeData.key,key)==0)     
{
node->nextNode=htemp->nextNode;  //找到之后node指向htemp指向的 链表就跳过了htemp 从而实现删除
free(htemp);                         //把跳过的htemp内存释放;
return 1;
}
else
{
node = htemp;               //node成为htemp
htemp=htemp->nextNode;      //htemp成为下一个
//这样node就指向了htemp
}
}
return 0;
/*方法说明:while第一次循环时htemp指针和node都为head,所以if方法不执行先执行
else,else方法中node与htemp指针相同 , 然后htemp指针成为下一个结点的指针,从而
node指针一直在htemp指针后面。
当if方法执行了,htemp为要删除的结点指针,node为其上一个指针
*/
}








int CLLength(CLType *head)         //计算链表的长度
{
CLType *htemp;
int Len=0;
htemp = head;
while(htemp)
{
Len++;
htemp=htemp->nextNode;        //指针不为空就len加一
}
return Len;
}


void CLAllNode(CLType *head)   //遍历列表
{
CLType *htemp;
Data nodeData;
htemp=head;
printf("当前列表共有%d个结点。链表所有数据如下:\n",CLLength(head));


while(htemp)
{
nodeData=htemp->nodeData;
printf("结点(%s,%s,%d)\n",nodeData.key,nodeData.name,&nodeData.age);
htemp=htemp->nextNode;
}
}




void main()
{
CLType *node,*head=NULL;
Data nodeData;
char key[10],findkey[10];
printf("链表测试。先输入链表中的数据,格式为: 关键字 姓名 年龄\n");
do
{
fflush(stdin);
scanf("%s",nodeData.key);
if(strcmp(nodeData.key,"0")==0)
{
break; //若输入0,则退出
}
else
{
scanf("%s,%d",&nodeData.name,&nodeData.age);
head=CLAddEnd(head,nodeData);
}
}while(1);
CLAllNode(head);      //显示所有结点
printf("\n演示插入结点,输入插入位置的关键字:");
scanf("%s",&findkey);
printf("输入插入结点的数据(关键字 姓名 年龄):");
scanf("%s,%s,%d",nodeData.key,nodeData.name,nodeData.age);
head=CLInsertNode(head,findkey,nodeData);   //调用插入函数
CLAllNode(head);  


printf("\n演示删除结点,输入要删除的关键字:");  //删除结点
fflush(stdin);
scanf("%s",&key);
CLDeleteNode(head,key);
CLAllNode(head);


printf("\n演示在链表中查找,输入查找关键字:");
fflush(stdin);
scanf("%s",key);
node=CLFindNode(head,key);
if(node)
{
nodeData=node->nodeData;
printf("关键字%s对应的结点为(%s,%s,%d)\n",key,nodeData.key,nodeData.name,nodeData.age);
}
else
{
printf("在链表中未找到关键字为%s的结点!\n",key);
}




原创粉丝点击