C语言 翁凯老师 数据结构 链表学习(1)
链表的建立
linked-list.c
#include"node.h"
#include<stdio.h>
#include<stdlib.h>
// typedef struct _node
// {
// int value;
// struct _node *next;
// } Node;
int main()
{
Node * head = NULL;//初始化
int number;
do{
scanf("%d",&number);
if(number != 1){
//add to linked-list
Node *p = (Node*)malloc(sizeof(Node));
p->value = number;
p->next = NULL;
//find the last
Node *last = head;
if(last){
while (last->next){//遍历到last->next=NULL为止,保证数据存储在链表的最后一位
last = last->next;
}
//attach
last->next = p;
}else{
head = p;
}
}
}while (number != -1);
printf("%d",head->value);//为了验证链表的有效性
return 0;
}
node.h
#ifndef _NODE_H_
#define _NODE_H_
typedef struct _node
{
int value;
struct _node *next;
} Node;
#endif
链表的函数
缺点:要求 使用add函数的程序员 必须做这件事情,但是我们没有办法强制他人做这件事情【如果没有head=add()对空链表不做这件事情的话就是错的】
#include"node.h"
#include<stdio.h>
#include<stdlib.h>
// typedef struct _node
// {
// int value;
// struct _node *next;
// } Node;
Node* add(Node *head,int number);
// 如果是void add 函数的话就要使用全局变量Node*head 但是,最好不要用全局变量,全局变量是有害的,程序只会是一次性的,只能对这一个链表有作用
int main()
{
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)
{
//add to linked-list
Node *p = (Node*)malloc(sizeof(Node));
p->value = number;
p->next = NULL;
//find the last
Node *last = head;
if(last){
while (last->next){//遍历到last->next=NULL为止,保证数据存储在链表的最后一位
last = last->next;
}
//attach
last->next = p;
}else{
head = p;
}
return head;
}
优化1:将*head变为**phead【head = add()没有改进】
#include"node.h" #include<stdio.h> #include<stdlib.h> // typedef struct _node // { // int value; // struct _node *next; // } Node; Node* add(Node** phead,int number); // 如果是void add 函数的话就要使用全局变量Node*head 但是,最好不要用全局变量,全局变量是有害的,程序只会是一次性的,只能对这一个链表有作用 int main() { 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** phead,int number) { //add to linked-list Node *p = (Node*)malloc(sizeof(Node)); p->value = number; p->next = NULL; //find the last Node *last = *phead; if(last){ while (last->next){//遍历到last->next=NULL为止,保证数据存储在链表的最后一位 last = last->next; } //attach last->next = p; }else{ head = p; } // return head; }
优化2:用自己定义的一种数据list,代表整个链表,方便以后做修改。
eg:可以在定义一个数据,让链表存储不需要总是从第一位开始搜寻,而直接从最后一位开始存储
#include"node.h" #include<stdio.h> #include<stdlib.h> // typedef struct _node // { // int value; // struct _node *next; // } Node; typedef struct _list { Node* head; // Node* tail; }List; void * add(List* plist,int number); // 如果是void add 函数的话就要使用全局变量Node*head 但是,最好不要用全局变量,全局变量是有害的,程序只会是一次性的,只能对这一个链表有作用 int main() { List list; list.head /* = list.tail */= NULL; int number; do{ scanf("%d",&number); if(number != 1){ add(&list,number); } }while (number != -1); return 0; } void * add(List* plist,int number) { //add to linked-list Node *p = (Node*)malloc(sizeof(Node)); p->value = number; p->next = NULL; //find the last Node *last = plist->head; if(last){ while (last->next){//遍历到last->next=NULL为止,保证数据存储在链表的最后一位 last = last->next; } //attach last->next = p; }else{ plist->head = p; } // return head; }
在List的中再创建一个tail指针代表尾结点,使tail永远指向新加进去的节点。这样让链表存储不需要总是从第一位开始搜寻,而直接从最后一位开始存储
#include"node.h" #include<stdio.h> #include<stdlib.h> // typedef struct _node // { // int value; // struct _node *next; // } Node; typedef struct _list { Node* head; Node* tail;//永远指向最后一个节点 }List; void * add(List* plist,int number); // 如果是void add 函数的话就要使用全局变量Node*head 但是,最好不要用全局变量,全局变量是有害的,程序只会是一次性的,只能对这一个链表有作用 int main() { List list; list.head = 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) { //add to linked-list Node *p = (Node*)malloc(sizeof(Node)); p->value = number; p->next = NULL; //find the last Node *last = plist->tail; if(last){ /* while (last->next){//遍历到last->next=NULL为止,保证数据存储在链表的最后一位 last = last->next; } // attach */ last->next = p; plist->tail = p; }else{ plist->head = p; plist->tail = p; } // return head; }