1.链表
什么是链表
链表是一种数据结构,是一种数据存放的思想
数组特点:元素地址连续
数组的缺点:增加、删除、改、查比较困难,特别是增加的时候,不够灵活
链表的每一项都是一个结构体
#include<stdio.h>
struct Test
{
int data;
struct Test *next;
};
int main()
{
int i;
int arr[] = {1,2,3,4};
for(i<0; i<sizeof(arr)/sizeof(arr[0]); i++){
printf("%d ",arr[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 print three nums\n");
printf("%d %d %d",t1.data,t1.next->data,t1.next->next->data);
return 0;
}
2.链表的静态添加和遍历
静态添加:
struct Test t1 = {1,NULL};
struct Test t2 = {2,NULL};
struct Test t3 = {3,NULL};
struct Test t4 = {4,NULL};//静态添加只需要再定义一个结构体
t1.next = &t2;
t2.next = &t3;
t3.next = &t4;//链表尾的next为下一个结构体的地址
遍历:
void printLink(struct Test *head)
{
struct Test *point;//定义一个节点来存储头结点
point = head;
while(1){
if(point != NULL)//如果point == NULL说明已经到了链表的尾部
{
printf("%d ",point->data);
point = point ->next;//每打印一次,
}
}
}
3.统计链表节点个数以及链表查找
3.1链表节点个数
int getLinkTotalNodeNum(struct Test *head)
{
int cnt = 0;
while(head != NULL){
cnt++;
head = head ->next;
}
return cnt;
}
3.2链表查找
int searchLink(struct Test *head,int a)
{
while(head != NULL){
if(a == head->data){
return 1;
}
head = head ->next;
}
return 0;
}
4.链表的插入
尾插法
int insertFromBehind(struct Test *head, int a, struct Test *new)
{
struct Test *point = head;
while (point != NULL)
{
if (point->data == a)
{
new->next = point->next;
point->next = new;
return 1;
}
point = point->next;
}
return 0;
}
头插法:
struct Test* insertFor(struct Test *head, int data, struct Test *new)
{
struct Test *p = head;
if (p->data == data)
{
new->next = head;
return new;
}
while(p->next != NULL){//当下一个节点的地址不为空时
printf("data = %d,point = %d\n",p->next->data,data);
if(p->next->data == data){
new ->next = p->next;
p->next = new;
printf("insert ok");
return head;
}
p = p->next;
}
printf("no this data%d",data);
return head;
}
5.链表的删除
struct Test *deletNote(struct Test *head,int data)
{
struct Test *p = head;
if(p->data == data){
head = head->next;
free(p);
return head;
}
while(p ->next != NULL){
if(p ->next->data == data){
//struct Test *temp = p;//动态链表采用这种形式
p->next = p->next->next;
//free(temp);
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};
p ->data = 1;
//t1.next = &t2;
p->next = &t2;
t2.next = &t3;
t3.next = &t4;
t4.next = &t5;
head = p;
printLink(head);
head = deletNote(head,5);
printLink(head);
//head = insertFor(head,4, &new);
//struct Test new = {100, NULL};
// deletNote(head,1);
return 0;
}
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};
p ->data = 1;
//t1.next = &t2;
p->next = &t2;
t2.next = &t3;
t3.next = &t4;
t4.next = &t5;
head = p;
printLink(head);
head = deletNote(head,5);
printLink(head);
//head = insertFor(head,4, &new);
//struct Test new = {100, NULL};
// deletNote(head,1);
return 0;
}
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};
p ->data = 1;
//t1.next = &t2;
p->next = &t2;
t2.next = &t3;
t3.next = &t4;
t4.next = &t5;
head = p;
printLink(head);
head = deletNote(head,5);
printLink(head);
//head = insertFor(head,4, &new);
//struct Test new = {100, NULL};
// deletNote(head,1);
return 0;
}
7.链表的动态创建:头插法、尾插法
头插法:
有一点问题,思想是这样的思想,但是打印出来会无限打印
#include <stdio.h> #include <stdlib.h> struct Test { int data; struct Test *next; }; void printLink(struct Test *head) { struct Test *point = head; while (point != NULL) { printf("%d ", point->data); point = point->next; } printf("\n"); } int insertFromBehind(struct Test *head, int a, struct Test *new) { struct Test *point = head; while (point != NULL) { if (point->data == a) { new->next = point->next; point->next = new; return 1; } point = point->next; } return 0; } struct Test* insertFor(struct Test *head, int data, struct Test *new) { struct Test *p = head; if (p->data == data) { new->next = head; return new; } while(p->next != NULL){ printf("data = %d,point = %d\n",p->next->data,data); if(p->next->data == data){ new ->next = p->next; p->next = new; printf("insert ok"); return head; } p = p->next; } printf("no this data%d",data); return head; } struct Test *deletNote(struct Test *head,int data) { struct Test *p = head; if(p->data == data){ head = head->next; free(p); return head; } while(p ->next != NULL){ if(p ->next->data == data){ //struct Test *temp = p; p->next = p->next->next; //free(temp); return head; } p = p->next; } return head; } struct Test* insertFromHead(struct Test *head,struct Test *new) { if(head == NULL){ head = new; }else{ new ->next = head; head = new; } return head; } struct Test *createLink(struct Test *head) { struct Test *new; while (1) { new = (struct Test *)malloc(sizeof(struct Test)); printf("input your new note data"); scanf("%d",&(new->data)); if(new->data == 0){ printf("0 quit!\n"); free(new); return head; } head = insertFromHead(head,new); } } int main() { struct Test *head = NULL; head = creatLink(head); printLink(head); struct Test t1 = {1000,NULL}; head = insertFromHead(head,&t1); printLink(head); return 0; }
尾插法:
struct Test *insertBehind(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;
}