本文章针对方向有:链表创建、遍历、找数字、删除节点、添加节点、反向输出案例、释放链表;
由于第一次发表不太知道具体写什么,因为在本人查找链表时,发现查出来的案例大多数很高级,不是很"亲民",站在同样刚学完c语言的角度,写了几个很基础的链表样例分享一下,希望可以对同为初学者的你有些帮助!
(因为属于个人打的代码,很对方法可能有些个人特色,不是特别传统,但是还是希望可以在思维上有些帮助)
因为本人能力有限,如果有出错,或者可以改进的地方,非常非常非常,愿意接受整改(可以进步了,哈哈)
下面是完整代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct _node{
//本节点储存的数字
int val;
//指向下一个节点
_node* next;
}node;
node *add(node *head,int number);
void bianli(node *head);
void find(node *head,int number);
void del(node *head,int number);
node *_more(node *head,int number,int more);
void back(node *head);
int main()
{
node *head=NULL;
int number;
//输入
printf("请输入数字(-1截至):\n");
do{
scanf("%d",&number);
if(number!=-1){
//如果用void,在函数里改变的head,不能改变原head指针
//所以要返回指针
head=add(head,number);
}
}while(number!=-1);
//遍历
bianli(head);
//找数字
printf("找数字:\n");
scanf("%d",&number);
find(head,number);
//删除节点
printf("要删除的数字:\n");
scanf("%d",&number);
del(head,number);
//添加节点
printf("在哪个数字后面添加:\n");
scanf("%d",&number);
int more;
printf("添加的数字:\n");
scanf("%d",&more);
head=_more(head,number,more);
bianli(head);
//反向输出
printf("反向输出:\n");
back(head) ;
//释放链表
node *p,*q=NULL;
for(p=head;p;p=q){
//q指向下一节点,释放p,然后下一轮p指向q,也就是到了下一位置
q=p->next;
free(p);
}
return 0;
}
node *add(node *head,int number)
{
//为新节点申请空间
node *p;
p=(node*)malloc(sizeof(node));
//初始化新节点
p->val=number;
p->next=NULL;
//找到最后一位节点
node *last=head;
//last不是是空,也就last不是空的head
if(last){
while(last->next){
last=last->next;
}
//找到最后一位,把p接在后面
last->next=p;
}
//如果last是空head,也就是第一次添加节点,那就把p放在head上就好
else{
head=p;
}
return head;
}
void bianli(node *head)
{
node *p;
for(p=head;p;p=p->next){
printf("%d\t",p->val);
}
printf("\n");
}
void find(node *head,int number)
{
node *p;
int flag=1;
for(p=head;p;p=p->next){
if(p->val==number){
printf("找到了!\n");
flag=0;
break;
}
}
if(flag) printf("没找到!\n");
}
void del(node *head,int number)
{
node *p,*q;
//q为q的上一个节点,在把p删除时,要把q的节点接触到p的下一个(跳过p)
for(q=NULL,p=head;p;q=p,p=p->next)
{
if(p->val==number){
//确保q存在,如果q是NULL,也就是删除的是第一个,则p就没有前一个指针
//只要出现在赋值里面的指针要保证存在,在for里已经保证p存在,需要再保证q存在
if(q){
q->next=p->next;
free(p);
}
//如果删除第一个节点,就把head接到下一个
else{
head=p->next;
//别忘记释放这个节点
free(p);
}
break;
}
}
bianli(head);
}
node *_more(node *head,int number,int more)
{
node *p;
for(p=head;p;p=p->next)
{
if(p->val==number)
{
//申请新节点 ,并初始化
node *q=(node*)malloc(sizeof(node));
q->val=more;
//原:1->2
//让q的下一个接到q的下一个 ,(1->2,3->2)
q->next=p->next;
//让p的下一个回接到q(1->3,3->2)
p->next=q;
//现在:1->3->2
}
}
return head;
}
void back(node *head)
{
node *p=head,*q;
while(p->next) p=p->next;
//把p反在最后一个节点并输出
printf("%d\t",p->val);
int flag=1;
while(flag){
//把q放在p的前一个节点 ,为了p下一次可以前移
for(q=head;q;q=q->next){
if(q->next==p) break;
}
//把p重新排列,到与q在同一节点停止,相当于前移了一位
for(p=head;p;p=p->next){
if(p==q) break;
}
printf("%d\t",p->val);
//如果p到了头节点,跳出循环
if(p==head) flag=0;
}
printf("\n");
}
谢谢观看!
-----来自DUT