1.链表的基本概念
1.1链表引出
数组有缺陷 静态空间,一旦分配内存就不可以动态扩展,要不分配不够,要不分配过多 对于数组头部进行插入和删除效率低
1.2链表的组成
链表是由节点组成的 节点由数据域和指针域组成 struct LinkNode {int num, struct LinkNode *next};
1.3链表的分类
方式1 静态链表 动态链表 方式2 单向链表 双向链表 单向循环链表 双向循环链表
2.静态链表和动态链表
2.1 静态链表 创建在栈上
2.2 动态链表 创建在堆区
#include <stdio.h>
#include <stdlib.h>
struct LinkNode
{
int num;
struct LinkNode * next;
} ;
void test02 ( )
{
struct LinkNode * node1;
struct LinkNode * node2;
struct LinkNode * node3;
struct LinkNode * node4;
struct LinkNode * node5;
node1 = ( struct LinkNode * ) malloc ( sizeof ( struct LinkNode) ) ;
node2 = ( struct LinkNode * ) malloc ( sizeof ( struct LinkNode) ) ;
node3 = ( struct LinkNode * ) malloc ( sizeof ( struct LinkNode) ) ;
node4 = ( struct LinkNode * ) malloc ( sizeof ( struct LinkNode) ) ;
node5 = ( struct LinkNode * ) malloc ( sizeof ( struct LinkNode) ) ;
node1-> num = 10 ;
node2-> num = 20 ;
node3-> num = 30 ;
node4-> num = 40 ;
node5-> num = 50 ;
node1-> next = node2;
node2-> next = node3;
node3-> next = node4;
node4-> next = node5;
node5-> next = NULL ;
struct LinkNode * pCurrent = node1;
while ( pCurrent != NULL )
{
printf ( "%d\n" , pCurrent-> num) ;
pCurrent = pCurrent-> next;
}
free ( node1) ;
free ( node2) ;
free ( node3) ;
free ( node4) ;
free ( node5) ;
}
int main ( )
{
test02 ( ) ;
return 0 ;
}
3 链表的基本使用
3.1 在头结点链表 好处在于 头结点永远都是固定的
3.2 初始化链表 struct LinkNode *pHead = init_Linklist();
3.3遍历链表 void foreach_Linklist(struct LinkNode *pHead);
3.4插入链表 void insert_Linklist(struct LinkNode *pHead, int oldVal, newVal);
在oldval前插入 newval,如果没有oldval就进行尾插
3.5删除链表 void delete_Linklist(struct LinkNode *pHead, int val);
用户提供的有效数据 删除掉 无效数据 直接return
3.6清空链表 void clear_Linklist(struct LinkNode *pHead);
将所有有数据的节点释放掉
3.7销毁链表 void destroy_Linklist(struct LinkNode *pHead);
将整个链表都释放掉
代码:
linklist.h
struct LinkNode
{
int num;
struct LinkNode * next;
} ;
struct LinkNode * init_Linklist ( ) ;
void foreach_Linklist ( struct LinkNode * pHead) ;
void insert_Linklist ( struct LinkNode * pHead, int oldVal, int newVal) ;
void delete_Linklist ( struct LinkNode * pHead, int val) ;
void clear_Linklist ( struct LinkNode * pHead) ;
void destroy_Linklist ( struct LinkNode * pHead) ;
linklist.c
#include <stdio.h>
#include "linklist.h"
#include <stdlib.h>
struct LinkNode * init_Linklist ( ) {
struct LinkNode * pHead;
struct LinkNode * pTail;
pHead = ( struct LinkNode * ) malloc ( sizeof ( struct LinkNode) ) ;
pHead-> next = NULL ;
pTail = pHead;
if ( pHead == NULL ) {
return NULL ;
}
pHead-> next = NULL ;
int val = - 1 ;
while ( 1 ) {
printf ( "input num, input -1 out\n" ) ;
scanf ( "%d" , & val) ;
if ( val == - 1 ) {
break ;
}
struct LinkNode * newNode;
newNode = ( struct LinkNode * ) malloc ( sizeof ( struct LinkNode) ) ;
newNode-> num = val;
newNode-> next = NULL ;
pTail-> next = newNode;
pTail = newNode;
}
return pHead;
}
void foreach_Linklist ( struct LinkNode * pHead) {
struct LinkNode * pCurrent;
pCurrent = pHead-> next;
while ( pCurrent != NULL ) {
printf ( "%d\n" , pCurrent-> num) ;
pCurrent = pCurrent-> next;
}
}
void insert_Linklist ( struct LinkNode * pHead, int oldVal, int newVal) {
if ( pHead == NULL ) {
return ;
}
struct LinkNode * pPrev = pHead;
struct LinkNode * pCurrent = pHead-> next;
while ( pCurrent != NULL ) {
if ( pCurrent-> num == oldVal) {
break ;
}
pPrev = pCurrent;
pCurrent = pCurrent-> next;
}
struct LinkNode * newNode;
newNode = ( struct LinkNode * ) malloc ( sizeof ( struct LinkNode) ) ;
newNode-> num = newVal;
newNode-> next = NULL ;
newNode-> next = pCurrent;
pPrev-> next = newNode;
}
void delete_Linklist ( struct LinkNode * pHead, int val) {
if ( pHead == NULL )
{
return ;
}
struct LinkNode * pPrev = pHead;
struct LinkNode * pCurrent = pHead-> next;
while ( pCurrent != NULL ) {
if ( pCurrent-> num == val) {
break ;
}
pPrev = pCurrent;
pCurrent = pCurrent-> next;
}
if ( pCurrent == NULL ) {
return ;
}
pPrev-> next = pCurrent-> next;
free ( pCurrent) ;
pCurrent = NULL ;
}
void clear_Linklist ( struct LinkNode * pHead)
{
if ( pHead == NULL )
{
return ;
}
struct LinkNode * pCurrent = pHead-> next;
while ( pCurrent != NULL )
{
struct LinkNode * Nodenext = pCurrent-> next;
free ( pCurrent) ;
pCurrent = Nodenext;
}
pHead-> next = NULL ;
}
void destroy_Linklist ( struct LinkNode * pHead)
{
if ( pHead == NULL )
{
return ;
}
clear_Linklist ( pHead) ;
free ( pHead) ;
pHead = NULL ;
}
主函数
#include <stdio.h>
#include "linklist.h"
void test01 ( ) {
struct LinkNode * pHead = init_Linklist ( ) ;
printf ( "output linklist:\n" ) ;
foreach_Linklist ( pHead) ;
insert_Linklist ( pHead, 10 , 100 ) ;
insert_Linklist ( pHead, 20 , 200 ) ;
insert_Linklist ( pHead, - 1 , 300 ) ;
printf ( "after linklist:\n" ) ;
foreach_Linklist ( pHead) ;
delete_Linklist ( pHead, 30 ) ;
delete_Linklist ( pHead, 100 ) ;
delete_Linklist ( pHead, 1000 ) ;
printf ( "after after linklist:\n" ) ;
foreach_Linklist ( pHead) ;
clear_Linklist ( pHead) ;
printf ( "clear linklist:\n" ) ;
foreach_Linklist ( pHead) ;
insert_Linklist ( pHead, 111 , 111 ) ;
insert_Linklist ( pHead, 222 , 222 ) ;
insert_Linklist ( pHead, 333 , 333 ) ;
printf ( "create the new linklist:\n" ) ;
foreach_Linklist ( pHead) ;
destroy_Linklist ( pHead) ;
pHead = NULL ;
printf ( "destroy after:\n" ) ;
}
int main ( ) {
test01 ( ) ;
return 0 ;
}
测试结果:
input num, input - 1 out
10
input num, input - 1 out
20
input num, input - 1 out
30
input num, input - 1 out
- 1
output linklist:
10
20
30
after linklist:
100
10
200
20
30
300
after after linklist:
10
200
20
300
clear linklist:
create the new linklist:
111
222
333
destroy after: