全书链接: 408笔记——数据结构(C语言版)(将书上例题用C语言列出来,可以直接在IDE(Xcode)上运行)
2.1 动态单链表
单链表:每个结点只包含一个指针域的链表
main.c
#include <stdio.h>
#include <stdlib.h>
//#include "sequentialStorage.h"
#include "linkStorage.h"
int main(int argc, const char * argv[]) {
// insert code here...
printf("Hello, World!\n");
// sequentialStorageTest();
linkStorageTest();
return 0;
}
common.h(common.c是空的)
#ifndef common_h
#define common_h
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef int Status;
#endif /* common_h */
linkStorage.h
//
// linkStorage.h
// Ctest
//
// Created by macvivi on 2019/10/30.
// Copyright © 2019 macvivi. All rights reserved.
//
//链式存储(链式线性表)
#ifndef linkStorage_h
#define linkStorage_h
#include <stdio.h>
#include"common.h"
//28页
typedef struct LNode{
ElemType data;
struct LNode *next;
} LNode, LinkList;
//链式线性表测试代码
void linkStorageTest(void);
//遍历链表
void bianliLS(LinkList *L);
//建立一个带头结点的单链表 30页 算法2.10
LinkList * CreateList_L(int n);
//获取链表中第i个元素的值 29页
ElemType GetElem_L(LinkList *L,int i);
//在单链表L中第i个位置之前插入元素e 29页 算法2.8
Status ListInsert_L(LinkList *L, int i, ElemType e);
//在带头结点的单联表L中,删除第i个元素,并返回其值 30页 算法2.9
ElemType ListDelete_L(LinkList *L, int i);
//合并单链表 31页 算法2.11 以算法2.1为例
LinkList *MergeList_L(LinkList *La,LinkList *Lb);
#endif /* linkStorage_h */
linkStorage.c
//
// linkStorage.c
// Ctest
//
// Created by macvivi on 2019/10/30.
// Copyright © 2019 macvivi. All rights reserved.
//
#include "linkStorage.h"
void linkStorageTest(void){
LinkList *L= CreateList_L(3);
bianliLS(L);
ElemType e = GetElem_L(L, 2);
printf("%d\n",e);
printf("--------\n");
ListInsert_L(L, 3, 9);
bianliLS(L);
ElemType a = ListDelete_L(L, 4);
printf("%d\n",a);
printf("---------------\n");
bianliLS(L);
printf("两个单链表的合并\n");
LinkList *La = CreateList_L(0);
ListInsert_L(La, 1, 3);
ListInsert_L(La, 2, 5);
ListInsert_L(La, 3, 8);
ListInsert_L(La, 4, 11);
bianliLS(La);
LinkList *Lb = CreateList_L(0);
ListInsert_L(Lb, 1, 2);
ListInsert_L(Lb, 2, 6);
ListInsert_L(Lb, 3, 8);
ListInsert_L(Lb, 4, 9);
ListInsert_L(Lb, 5, 11);
ListInsert_L(Lb, 6, 15);
ListInsert_L(Lb, 7, 20);
bianliLS(Lb);
LinkList *Lc = MergeList_L(La, Lb);
bianliLS(Lc);
}
LinkList *MergeList_L(LinkList *La,LinkList *Lb){
//已知单链线性表La和Lb的元素按值非递减排列
//归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列
LinkList *pa = La->next;
LinkList *pb = Lb->next;
LinkList *pc = La; //用La的头结点作为Lc的头结点
while (pa && pb) {
if (pa->data <= pb->data) {
pc->next = pa;
pc = pa;
pa = pa->next;
} else {
pc->next = pb;
pc = pb;
pb = pb->next;
}
}
pc->next = pa?pa:pb; //插入剩余段
free(Lb); //释放Lb的头结点
return La;
}
ElemType ListDelete_L(LinkList *L, int i){
LinkList *p = L;
int j = 0;
while (p->next && j < i-1) {
p = p->next;//寻找第i个结点,并令p指向其前趋
j++;
}
if (!(p->next) || j > i-1) {
return 0;
}
//删除并释放结点
LinkList *q = p->next;
p->next = q->next;
ElemType e = q->data;
free(q);
return e;
}
Status ListInsert_L(LinkList *L, int i, ElemType e){
LinkList *p = L;
int j = 0;
while (p && j < i-1) {
p = p->next; //寻找第i-1个节点
j++;
}
if (!p || j > i-1) {
return 0;
}
LinkList *s = (LinkList*)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return 1;
return 0;
}
ElemType GetElem_L(LinkList *L,int i){
//L为带头结点的单链表的头指针
//当第i个元素存在时,将其返回
LinkList *p = L->next;
int j = 1;
while (p && j<i) {
p = p->next;
j++;
}
if (!p || j>i) {
return 0; //第i个元素不存在
}
return p->data;
}
void bianliLS(LinkList *L){
LinkList *p = L;
while (p->next) {
p = p->next;
printf("%d\n",p->data);
}
printf("---------\n");
}
LinkList* CreateList_L(int n){
//逆位序输入n个元素的值,建立带表头结点的单链线性表L。
LinkList* L = (LinkList*)malloc(sizeof(LNode));
L->next = NULL; //先建立一个带头结点的单链表
for (int i=n; i > 0; i--) {
LinkList *p = (LinkList *)malloc(sizeof(LNode)); //生成新节点
// scanf("%d",&p->data);
p->data = i+100;
p->next = L->next;
L->next = p;
}
return L;
}
打印结果:
Hello, World!
101
102
103
---------
102
--------
101
102
9
103
---------
103
---------------
101
102
9
---------
两个单链表的合并
3
5
8
11
---------
2
6
8
9
11
15
20
---------
2
3
5
6
8
8
9
11
11
15
20
---------
Program ended with exit code: 0