一种数据存放思想
数组的元素存放地址是连续的,但缺点是增加和删除元素是复杂和内存消耗大的。而链表的存储空间是不连续的,它的每一个元素相当于一个结构体,如果有a,b,c三个元素,他们存储空间是不连续的,a有一个指针指向b的地址,b有一个指针指向c地址,就这样链接起来的一个表,如果要删除b,只要把a指针指向c地址即可完成。
#include <stdio.h>
struct Test
{
int data;
struct Test* next;
};
int main()
{
int i;
int array[] = {1,2,3};
for(i=0;i<sizeof(array)/sizeof(array[0]);i++){
printf("%d ",array[i]);
}
putchar('\n');
struct Test t1 = {1,NULL};
struct Test t2 = {2,NULL};
struct Test t3 = {3,NULL};
t1.next = &t2;
t2.next = &t3;
printf("use t1 to point three nums\n");
printf("%d %d %d\n",t1.data,t1.next->data,t1.next->next->data);//又叫链表头
return 0;
}
>>>
1 2 3
use t1 to point three nums
1 2 3
静态添加和动态遍历链表
#include <stdio.h>
struct Test
{
int data;
struct Test* next;
};
void printLink(struct Test* head)
{
while(head != NULL){
printf("%d ",head->data);
head = head->next;
}
}
int main()
{
struct Test t1 = {1,NULL};
struct Test t2 = {2,NULL};
struct Test t3 = {3,NULL};
struct Test t4 = {4,NULL};
struct Test t5 = {5,NULL};
struct Test t6 = {6,NULL};
t1.next = &t2;
t2.next = &t3;
t3.next = &t4;
t4.next = &t5;
t5.next = &t6;
printf("use t1 to point nums\n");
printLink(&t1);
return 0;
}
统计链表节点个数及链表查找
#include <stdio.h>
struct Test
{
int data;
struct Test* next;
};
void printLink(struct Test* head)
{
while(head != NULL){
printf("%d ",head->data);
head = head->next;
}
putchar('\n');
}
int getLinkNodeNum(struct Test* head)
{
int cnt = 0;
while(head != NULL){
cnt ++;
head = head->next;
}
return cnt;
}
int searchLink(struct Test* head,int num)
{
while(head != NULL){
if(head->data == num){
return 1;
}
head = head->next;
}
return 0;
}
int main()
{
struct Test t1 = {1,NULL};
struct Test t2 = {2,NULL};
struct Test t3 = {3,NULL};
struct Test t4 = {4,NULL};
struct Test t5 = {5,NULL};
struct Test t6 = {6,NULL};
t1.next = &t2;
t2.next = &t3;
t3.next = &t4;
t4.next = &t5;
t5.next = &t6;
printf("use t1 to point nums\n");
printLink(&t1);
int ret = getLinkNodeNum(&t1);
printf("这个链表有%d个节点\n",ret);
ret = searchLink(&t1,1);
if(ret == 0){
printf("no 1\n");
}else{
printf("have 1\n");
}
ret = searchLink(&t1,8);
if(ret == 0){
printf("no 8\n");
}else{
printf("have 8\n");
}
return 0;
}
use t1 to point nums
1 2 3 4 5 6
这个链表有6个节点
have 1
no 8
后方插入新节点
#include <stdio.h>
struct Test
{
int data;
struct Test* next;
};
void printLink(struct Test* head)
{
struct Test* p = head;
while(p != NULL){
printf("%d ",p->data);
p = p->next;
}
putchar('\n');
}
int insertFromBehind(struct Test* head,int data,struct Test* new)
{
struct Test* p = head;
while(p != NULL){
if(p->data == data){
new->next = p->next;//顺序不能换,否则链表会断掉
p->next = new;
return 1;
}
p = p->next;
}
return 0;
}
int main()
{
struct Test t1 = {1,NULL};
struct Test t2 = {2,NULL};
struct Test t3 = {3,NULL};
struct Test t4 = {4,NULL};
struct Test t5 = {5,NULL};
struct Test t6 = {6,NULL};
t1.next = &t2;
t2.next = &t3;
t3.next = &t4;
t4.next = &t5;
t5.next = &t6;
struct Test new = {100,NULL};
printf("use t1 to point nums\n");
printLink(&t1);
puts("after insert behind:");
insertFromBehind(&t1,3,&new);
printLink(&t1);
return 0;
}
前方插入新节点
#include <stdio.h>
struct Test
{
int data;
struct Test* next;
};
void printLink(struct Test* head)
{
struct Test* p = head;
while(p != NULL){
printf("%d ",p->data);
p = p->next;
}
putchar('\n');
}
struct Test* insertFromFront(struct Test* head,int data,struct Test* new)
{
struct Test* p = head;
//在头节点插入
if(p->data == data){
new->next = p;
return new;
}
//在中间节点插入
while(p->next != NULL){
if(p->next->data == data){
new->next = p->next;
p->next = new;
return head;
}
p = p->next;
}
printf("don't have this data\n");
return head;
}
int main()
{
struct Test* head = NULL;
struct Test t1 = {1,NULL};
struct Test t2 = {2,NULL};
struct Test t3 = {3,NULL};
struct Test t4 = {4,NULL};
struct Test t5 = {5,NULL};
struct Test t6 = {6,NULL};
t1.next = &t2;
t2.next = &t3;
t3.next = &t4;
t4.next = &t5;
t5.next = &t6;
head = &t1;
printf("use t1 to point nums\n");
printLink(head);
struct Test new = {111,NULL};
head = insertFromFront(head,2,&new);
puts("after insert front:");
printLink(head);
return 0;
}
删除节点
#include <stdio.h>
#include <stdlib.h>
struct Test
{
int data;
struct Test* next;
};
void printLink(struct Test* head)
{
struct Test* p = head;
while(p != NULL){
printf("%d ",p->data);
p = p->next;
}
putchar('\n');
}
struct Test* deleteLink(struct Test* head,int data)
{
struct Test* p = head;
if(p->data == data){
head = head->next;
free(p);//静态链表中free要结合malloc使用
return head;
}
while(p->next != NULL){
if(p->next->data == data){
//struct Test* tmp = p;//动态
p->next = p->next->next;
//free(tmp);
return head;
}
p = p->next;
}
return head;
}
int main()
{
struct Test* head = NULL;
// struct Test t1 = {1,NULL};
struct Test* p = (struct Test*)malloc(sizeof(struct Test));
struct Test t2 = {2,NULL};
struct Test t3 = {3,NULL};
struct Test t4 = {4,NULL};
struct Test t5 = {5,NULL};
struct Test t6 = {6,NULL};
// t1.next = &t2;
p->data = 1;
p->next = &t2;
t2.next = &t3;
t3.next = &t4;
t4.next = &t5;
t5.next = &t6;
// head = &t1;
head = p;
printf("use t1 to point nums\n");
printLink(head);
head = deleteLink(head,6);
printLink(head);
return 0;
}
头插法创建动态链表
#include <stdio.h>
#include <stdlib.h>
struct Test
{
int data;
struct Test* next;
};
void printLink(struct Test* head)
{
struct Test* p = head;
while(p != NULL){
printf("%d ",p->data);
p = p->next;
}
putchar('\n');
}
struct Test* createFromHead(struct Test* head)
{
struct Test* new;
while(1){
new = (struct Test*)malloc(sizeof(struct Test));
new->next = NULL;//记得初始化,否则后面的printLink就会变成死循环
puts("input your new node data:");
scanf("%d",&(new->data));
if(new->data == 0){
printf("0 Quit\n");
return head;
}
if(head == NULL){
head = new;
}else{
new->next = head;
head = new;
}
}
return head;
}
int main()
{
struct Test* head = NULL;
head = createFromHead(head);
printLink(head);
return 0;
}
优化
#include <stdio.h>
#include <stdlib.h>
struct Test
{
int data;
struct Test* next;
};
void printLink(struct Test* head)
{
struct Test* p = head;
while(p != NULL){
printf("%d ",p->data);
p = p->next;
}
putchar('\n');
}
struct Test* createFromHead(struct Test* head,struct Test* new)
{
if(head == NULL){
head = new;
}else{
new->next = head;
head = new;
}
return head;
}
struct Test* creatLink(struct Test* head)
{
struct Test* new;
while(1){
new = (struct Test*)malloc(sizeof(struct Test));
new->next = NULL;
puts("input your new node data:");
scanf("%d",&(new->data));
if(new->data == 0){
printf("0 Quit\n");
return head;
}
head = createFromHead(head,new);
}
}
int main()
{
struct Test* head = NULL;
head = creatLink(head);
printLink(head);
/*struct Test* t1 = {100,NULL};
head = createFromHead(head,&t1);
printLink(head);*/
return 0;
}
尾插法
#include <stdio.h>
#include <stdlib.h>
struct Test
{
int data;
struct Test* next;
};
void printLink(struct Test* head)
{
struct Test* p = head;
while(p != NULL){
printf("%d ",p->data);
p = p->next;
}
putchar('\n');
}
struct Test* creatFromBehind(struct Test* head,struct Test* new)
{
struct Test* p = head;
if(p == NULL){
head = new;
return head;
}
while(p->next != NULL){
p = p->next;
}
p->next = new;
return head;
}
struct Test* creatLink(struct Test* head)
{
struct Test* new;
while(1){
new = (struct Test*)malloc(sizeof(struct Test));
new->next = NULL;
puts("input your new node data:");
scanf("%d",&(new->data));
if(new->data == 0){
printf("0 Quit\n");
return head;
}
head = creatFromBehind(head,new);
}
}
int main()
{
struct Test* head = NULL;
head = creatLink(head);
//struct Test t1 = {2000,NULL};
//head = creatFromBehind(head,&t1);
printLink(head);
return 0;
}