C语言的学习日志2.19

链表:

链表是一种基础数据结构,采用动态分配储存单元的方式进行储存分配。结构体指针在这上面得到了充分的运用。换句话说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节点。

创建链表:

首先,要先构造一个结构体,构造结构体一般都用typedef函数,这样方便结构体变量的命名。

typedef struct _node{
    int value;
    struct _node *next;
}Node;

然后再构造节点,再构造节点之前我们先来了解下:

        p = head->nexthead->next=p的区别:

                p= head->next的意思是原本head指针指向next,将这个赋值给p,也就相当于显示这个指针,即p也指向next。

                head->next=p的意思是改变next的指向,next指向p这个新的节点。

构造节点如下:

Node *p = (Node*)malloc(sizeof(Node));
p->value = number;
p->next = NULL;//注意最后p指针是指向next,方便后面的连接

下一步就是构建这个链表的最后一个指针:

Node *last = head;//先让last指向head,因为链表可能就一个节点
while(last->head){
    last = last->next;
}

最后就是将他们串联起来就行了。

整个内容如下:

typedef struct _node{
    int value;
    struct _node *next;
}Node;
int main(int argc, char const *argv[])
{
    Node *head = NULL;
    int number;
    do{
        scanf("%d",&number);
        if(number !=-1){
            Node *p = (Node*)malloc(sizeof(Node));
            p->next = number;
            p->next = NULL;
            Node *last = head;
            if(last){
                while(last ->next){
                    last = last->next;
                }
                last->next = p;
            }esle{
                head = p;
            }
        }
    }while(number !=-1);
}
            
        

让我们对上述进行一下优化,我们先用一个函数块,来将加入节点这个操作放入函数块中:

Node* add(Node* head,int number)
{
    Node *p = (Node*)malloc(sizeof(Node));
    p->next = number;
    p->next = NULL;
    Node *last = head;
    if(last){
        while(last ->next){
            last = last->next;
        }
        last->next = p;
    }else{
        head = p;
    }
    return head;
}

注意这时候用的是一个二级指针,因为函数中改变指针的指向,主函数中的指针是不会发生任何变化的,但是如果是改变指针所指的内容,这个时候主函数中的指针的内容是会变的,我们可以理解为函数重新复制了一个和主函数一样的指针。

整个也就是这样的:

#include <stdio.h>
#include <stdlib.h>
typedef struct _node{
	int value;
	struct _node *next;
}Node; 
Node* add(Node *head,int number); 
int main(int argc, char *argv[])
{
	Node *head=NULL;
	int number;
	do{
		scanf("%d",&number);
		if(number!=-1){
		head=add(head,number);
		}
	}while(number!=-1);
	printf("%d",head->value);
	return 0;
}
Node* add(Node *head,int number)
{
	Node *p=(Node*)malloc(sizeof(Node));
		p->value=number;
		p->next=NULL; 
		Node *last=head;
		if(last){
			while(last->next){
			last=last->next;
			}
		last->next=p;
		}else{
			head=p;
		}
}

然后我们可以再次改进,新建一个结构体_list来表示整个链表,还可以方便以后调整。

#include <stdio.h>
#include <stdlib.h>
typedef struct _node{
	int value;
	struct _node *next;
}Node; 
typedef struct _list{
	Node* head;
}List; 
void * add(List *list,int number);
int main(int argc, char *argv[])
{
	List list;
	list.head=NULL;
	int number;
	do{
		scanf("%d",&number);
		if(number!=-1){
	    add(&list,number);
		}
	}while(number!=-1);
	printf("%d",list.head->value);
	return 0;
}
void * add(List *list,int number)
{
	Node *p=(Node*)malloc(sizeof(Node));
		p->value=number;
		p->next=NULL; 
		Node *last=list->head;
		if(last){
			while(last->next){
			last=last->next;
			}
		last->next=p;
		}else{
		list->head=p;
		}
}

对于上述还是有需要改善的地方,last这个指针总是从head循环到最后指向最后一个,每新加一个节点,就要重新循环一次,很麻烦。所以需要增加一个tail指针

#include <stdio.h>
#include <stdlib.h>
#include "node.h"
typedef struct _list{
	Node* head;
	Node* tail;
}List; 
void * add(List *list,int number);
int main(int argc, char *argv[])
{
	List list;
	list.head=NULL;
	list.tail=NULL;
	int number;
	do{
		scanf("%d",&number);
		if(number!=-1){
	    add(&list,number);
//		head=add(head,number);
		}
	}while(number!=-1);
	printf("%d",list.tail->value);
	return 0;
}

void * add(List *plist,int number)
{
	Node *p=(Node*)malloc(sizeof(Node));
		p->value=number;
		p->next=NULL; 
		Node *last=list->head;
		if(last){
            last = plist ->tail;
		    last->next=p;
		    plist->tail=p;
		}else{
		    plist->head=p;
		    plist->tail=p;
		}
}

(以上内容是上翁恺老师的mooc课程上总结借鉴的)

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值