代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef int datatype;
typedef struct node{
datatype data;
struct node *next;
}node,*Linklist; //定义链表结点
node* createlist();//1.声明创建链表的函数
void print();//2.声明链表遍历的函数
void big();//3.声明链表长度的函数
void clear();//4.声明清除链表的函数
void null();//5.声明链表为空判断函数
int find();//6.声明查找函数
void getaddr();//7.声明根据定值找地址函数
void change();//8.声明修改某个节点值的函数
void inserthead();//9.声明表头插入函数
void inserttail();//10.声明表尾插入函数
void insertmiddle();//11.声明中间插入函数
void delet();//12.声明删除节点函数
node * createlist(node *head)//创建函数定义 ----->尾插法:
{
node *p1;//新节点
node *p2;//尾节点
p1=p2=(node*)malloc(sizeof(node));
if(p1==NULL || p2==NULL)
{printf("mallocerror!\n");}
scanf("%d",&(p1->data));
p1->next=NULL;
while(p1->data>0) //大于0的整数
{
if(head ==NULL)
{head =p1;//空表 p1为头节点
p2=head;}
else
{
p2->next=p1;
p2=p1;//保证p2为尾节点
}
p1=(node*)malloc(sizeof(node));
scanf("%d",&(p1->data));
}
free(p1);
p2->next=NULL;//尾节点的next为NULL
printf("create done!\n");
return head;
}
/*-------------------------------------------------
头插法:p->next=head;head=p; 遍历数据倒着输出
node * createlist(node *head)
{
node*p;
p=(node*)malloc(sizeof(node));
scanf("%d",&(p->data));
while(p->data>0)
{
p->next=head;
head=p;
p=(node*)malloc(sizeof(node));
scanf("%d",&(p->data));
}
return head;
}
------------------------------------------*/
void print(node *head)//链表遍历函数的定义
{
node *tmp;//定义临时指针去遍历
tmp =head;
while(tmp!=NULL)
{
printf("%d\n",tmp->data);
tmp =tmp->next;
}
printf("print done!\n");
return ;
}
void big(node *head)//链表长度函数长度
{
int listlong=0;
if(head ==NULL)
{ printf("listlong=0\n");
return ;
}
while(head !=NULL)
{
listlong++;
head=head->next;
}
printf("listlong done!andlistlong=%d\n",listlong);
return ;
}
void clear(node **head)//传入二级指针否则无法改变指针的地址值,无法删除节点
{
node *mv=NULL;//头节点的下个节点
if(*head ==NULL)
return ;//表空直接返回
while((*head)->next !=NULL)
{
mv=(*head)->next;//保存头节点的下个节点
free((*head));//删除头节点
(*head)=mv;//头节点下移
}
if((*head) != NULL)//最后一个节点!!!容易忘掉
{
free(*head);
*head =NULL;
}
printf("cleanlist done!\n");
return ;
}
void null(node *head)//链表是否为空判断定义
{
if(head ==NULL)
printf("List is NULL!\n");
else
printf("List is FULL!\n");
return ;
}
int find(node *head,int num)//查看链表第num个节点的数据
{
int i=0;
if(num<1 || head==NULL)
{
printf("find error:list is NULL or illegal input!\n");
}
while(head !=NULL)
{
i++;
if(i==num)
{
break;
}
head=head->next;
}
if(i<num)
{printf("find too long try again!\n");
return 0;
}
printf("find done!\n");
return head->data;
}
void getaddr(node *head,int x)//求地址
{
if(head==NULL || x<1)
{
printf("getaddr error:list is null or illegal input!\n");
return ;
}
while((head ->next!=NULL) && (head->data !=x))//链表未到表尾且没找到x!
{
head=head->next;
}
if((head !=NULL) && (head->data !=x))
{
printf("not found x in list and getaddr bad!\n");
return ;
}
if(head->data ==x)
printf("getdaddr done! x=%d ,addr=%p\n",x,&(head->data));
return ;
}
//****传入二级指针会改变头节点的地址,从而只能遍历出移动位置之后的链表值
void change(node *head,int i,datatype value1)//改变某个节点的值
{
int n=1;
node *nod=head;//临时节点去查找
if(i<1 || head==NULL)
{
printf("change error:list is NULL or illegal input!\n ");
return ;
}
while(head !=NULL)
{
if(n==i)
{
head=nod;
head->data=value1;//替换值
printf("change value done!\n");
break;
}
nod = nod->next;//移动节点
n++;
}
if(n<i)
{
printf("change value beyond list!\n");
return ;
}
return ;
}
void inserthead(node **head,datatype value1)//表头插入某值 表头需要动的用二级指针
{
node *insert;
if( head==NULL)
{
printf("change error:list is NULL or illegal input!\n ");
return ;
}
if(!(insert =(node*)malloc(sizeof(node))))
{
printf("malloc error!\n");
}
memset(insert,0,sizeof(node));
insert->data=value1;
insert->next=*head;
*head=insert;
printf("inserthead done!\n");
return ;
}
void inserttail(node *head,datatype value2)//表尾插入 需要中间节点去保存头节点
{
node* tmp;//保存头节点中间节点
node *insert;
tmp=head;//保存头节点
if( head==NULL)
{
printf("change error:list is NULL or illegal input!\n ");
return ;
}
if(!(insert =(node*)malloc(sizeof(node))))
{
printf("malloc error!\n");
}
memset(insert,0,sizeof(node));
insert->data=value2;
insert->next=NULL;//表尾为NULL
while((head)->next !=NULL)
{
(head)=(head)->next;//头节点移动直到表尾
}
(head)->next=insert; //插入节点到表尾
head=tmp;//中间节点=头节点
printf("inserttail done!\n");
return;
}
void insertmiddle(node *head,int i,datatype value3)
{
int n=1;
node * tmp; //临时节点保存头节点
node *insert;
node *next;
tmp=head;//保存头节点
if(i<1 || head==NULL)
{
printf("change error:list is NULL or illegal input!\n ");
return ;
}
while((head) !=NULL)
{
if(n==i)
{
if(!(insert =(node*)malloc(sizeof(node))))//找到后申请节点空间!
{
printf("malloc error!\n");
}
memset(insert,0,sizeof(node));
next=head->next;//保存当前节点的下一个节点!!!这二
insert->data=value3;//插入数据
(head)->next=insert;//插入节点
insert->next=next;//查入节点连入链表
//insert->next=(head)->next->next;//搞笑了。。。(head)->next->next不确定啊。。两侧都不确定
}
(head)=(head)->next;//移动节点
n++;
}
head=tmp;//还原头节点 只要不是二级指针就不会改变头节点这个其实多余!
printf("insertmiddle done!\n");
return ;
}
void delet(node **head,int i)//删除节点
{
int n=1;
node *tmp;
node *NODE;
NODE=*head;
if(i<1 || *head==NULL)
{
printf("change error:list is NULL or illegal input!\n ");
return ;
}
if(*head !=NULL)
{
if(n==i==1)//删除头节点!
{
printf("delete head node!\n");
tmp=(*head)->next;//保存第二个节点指针
(*head)->next=NULL;
*head=tmp;//第二个节点指针为头指针
return ;
}
while(n<i-1) //10----11
{
*head=(*head)->next;
if(((*head)->next) ==NULL)
{
printf("delete node beyond list!\n");
*head=NODE;//删除失败返回完整链表!
return;
}
n++;
}
tmp=(*head)->next;//保存删除节点指针
(*head)->next=(*head)->next->next;
free(tmp);
}
*head=NODE;
printf("delete node done!\n");
return;
}
int main()
{
int findnumber;
int m,mm,node,node1,node2,value,insert,insert1,insert2;
Linklist head1 =NULL; //初始化链表即是使表头指针为NULL,不必再定义函数。
head1 =createlist(head1);
print(head1);
big(head1);
printf("input number what you want find! inputnumber is:");
scanf("%d",&m);
if(findnumber=find(head1,m))
printf("find ok!findnumber=%d\n",findnumber);
printf("input data what you want get address! inputdata is:");
scanf("%d",&mm);
getaddr(head1,mm);
printf("input value and node what you want change!input two:");
scanf("%d,%d",&node,&value);
change(head1,node,value);
print(head1);
printf("input value what you want insert in head!input is:");
scanf("%d",&insert);
inserthead(&head1,insert);//头节点需要动的才传二级指针
printf("input value what you want insert in last!input is:");
scanf("%d",&insert1);
inserttail(head1,insert1);
printf("input value and node what you want insert in middle!input two is:");
scanf("%d,%d",&node1,&insert2);
insertmiddle(head1,node1,insert2);
print(head1);
printf("input node what you want delete in List!input is:");
scanf("%d",&node2);
delet(&head1,node2);
print(head1);
clear(&head1);//传入二级指针
big(head1);
null(head1);
return 0;
}