链表定义
链表是由一系列连接在一起的结点构成,其中的每个结点都是一个 数据结构 。 链表的结点通常是动态分配、使用和删除的,允许链表在程序运行时增大或缩小。 如果需要将新信息添加到链表中,则程序只需分配另一个结点并将其插入到系列中。 如果需要从链表中删除特定的信息块,则程序将删除包含该信息的结点。
代码分析
一,宏及结构体定义
#include <stdio.h>
#include <malloc.h>
/**
* 定义字符单链表。
*/
typedef struct LinkNode{
char data;
struct LinkNode *next;
} LNode, *LinkList, *NodePtr;
二,初始化链表
/**
* 初始化头节点。
* @return 返回头节点的指针。
*/
LinkList initLinkList(){
NodePtr tempHeader = (NodePtr)malloc(sizeof(LNode));
tempHeader->data = '\0';
tempHeader->next = NULL;
return tempHeader;
}
三,打印链表
/**
* 打印链表。
* @param paraHeader 是链表的头结点。
*/
void printList(NodePtr paraHeader){
NodePtr p = paraHeader->next;
if(p == NULL){
printf("The list is empty.");
}
while(p != NULL){
printf("%c", p->data);
p = p->next;
}
printf("\r\n");
}
四,在链表尾部插入元素
/**
* 在链表尾部添加元素。
* @param paraHeader 是链表的头结点。
* @param paraChar 给定的char元素。
*/
void appendElement(NodePtr paraHeader, char paraChar){
NodePtr p, q;
// Step 1. 创建一个新的节点
q = (NodePtr)malloc(sizeof(LNode));
q->data = paraChar;
q->next = NULL;
// Step 2. 搜索尾节点。
p = paraHeader;
while (p->next != NULL){
p =p->next;
}
// Step 3. 加入节点并和链表链接
p->next = q;
}
五,在给定的位置加入元素
/**
* 在给定的位置加入元素。
* @param paraHeader 是链表的头结点。
* @param paraChar 给定的char元素。
* @param paraPosition 给定的位置。
*/
void insertElementByPosition(NodePtr paraHeader, char paraChar, int paraPosition){
NodePtr p, q;
// Step 1. 搜索给定的位置。
p = paraHeader;
for(int i = 0; i < paraPosition; i ++){
p = p->next;
if(p == NULL){
printf("The position %d is beyond the scope of the list.", paraPosition);
return;
}
}
// Step 2. 创建一个新节点
q = (NodePtr)malloc(sizeof(LNode));
q->data = paraChar;
// Step 3. 链接链表和节点。
printf("linking\r\n");
q->next = p->next;
p->next = q;
}
六,在指定的元素前加入元素
/**
* 在给定的元素前加入元素。
* @param paraHeader 是链表的头结点。
* @param paraCharInsert 给定插入的char元素。
* @param paraChar 给定的元素。
*/
void insertElementByChar(NodePtr paraHeader, char paraCharInsert, int paraChar){
NodePtr p, q;
int flag = 0;
// Step 1. 搜索给定的元素。
p = paraHeader;
while (p->next != NULL){
p = p->next;
if(p->data == paraChar){
flag = 1;
break;
}
}
if(flag == 0){
printf("The Char %c is not in this list.\r\n", paraChar);
return;
}
// Step 2. 创建一个新节点
q = (NodePtr)malloc(sizeof(LNode));
q->data = paraCharInsert;
// Step 3. 链接链表和节点。
printf("linking\r\n");
q->next = p->next;
p->next = q;
}
七,删除指定元素
/**
* 删除链表中的元素。
* @param paraHeader 是链表的头结点。
* @param paraChar 给定的char元素。
*/
void deleteElement(NodePtr paraHeader, char paraChar){
NodePtr p, q;
p = paraHeader;
while((p->next != NULL) && (p->next->data != paraChar)){
p = p->next;
}
if(p->next == NULL){
printf("Cannot delete %c\r\n", paraChar);
return;
}
q = p->next;
p->next = p->next->next;
free(q);
}
八,摧毁链表
void LinkDestory(NodePtr paraHeader){
NodePtr p;
p = paraHeader;
p->next = NULL;
printf("The list has been destoryed.\r\n");
return;
}
九,功能测试
/**
* 功能测试。
*/
void appendInsertDeleteTest(){
// Step 1. 初始化一个空链表。
LinkList tempList = initLinkList();
printList(tempList);
// Step 2. 加入一些字符。
appendElement(tempList, 'H');
appendElement(tempList, 'e');
appendElement(tempList, 'l');
appendElement(tempList, 'l');
appendElement(tempList, 'o');
appendElement(tempList, '!');
printList(tempList);
// Step 3. 删除一些字符(第一次出现的)。
deleteElement(tempList, 'e');
deleteElement(tempList, 'a');
deleteElement(tempList, 'o');
printList(tempList);
// Step 4. 在链表给定位置插入特定元素。
insertElementByPosition(tempList, 'o', 1);
printList(tempList);
// Step 5. 在链表给定元素前插入特定元素。
insertElementByChar(tempList, 'a', 'o');
insertElementByChar(tempList, 'a', 'b');
printList(tempList);
// Step 6. 清空链表
LinkDestory(tempList);
printList(tempList);
}
十,程序入口
/**
* 程序入口。
*/
int main(){
appendInsertDeleteTest();
}
十一,总结
学习到了函数的传递有三种:值传递、指针传递(地址传递)、引用传递。
此外还可以引入新的功能例如在链表头部插入元素。
十二,运行结果
Hello!
Cannot delete a
Hll!
linking
Holl!
linking
The Char b is not in this list.
Hoall!
The list has been destoryed.
The list is empty.
完整代码
#include <stdio.h>
#include <malloc.h>
/**
* 定义字符单链表。
*/
typedef struct LinkNode{
char data;
struct LinkNode *next;
} LNode, *LinkList, *NodePtr;
/**
* 初始化头节点。
* @return 返回头节点的指针。
*/
LinkList initLinkList(){
NodePtr tempHeader = (NodePtr)malloc(sizeof(LNode));
tempHeader->data = '\0';
tempHeader->next = NULL;
return tempHeader;
}
/**
* 打印链表。
* @param paraHeader 是链表的头结点。
*/
void printList(NodePtr paraHeader){
NodePtr p = paraHeader->next;
if(p == NULL){
printf("The list is empty.");
}
while(p != NULL){
printf("%c", p->data);
p = p->next;
}
printf("\r\n");
}
/**
* 在链表尾部添加元素。
* @param paraHeader 是链表的头结点。
* @param paraChar 给定的char元素。
*/
void appendElement(NodePtr paraHeader, char paraChar){
NodePtr p, q;
// Step 1. 创建一个新的节点
q = (NodePtr)malloc(sizeof(LNode));
q->data = paraChar;
q->next = NULL;
// Step 2. 搜索尾节点。
p = paraHeader;
while (p->next != NULL){
p =p->next;
}
// Step 3. 加入节点并和链表链接
p->next = q;
}
/**
* 在给定的位置加入元素。
* @param paraHeader 是链表的头结点。
* @param paraChar 给定的char元素。
* @param paraPosition 给定的位置。
*/
void insertElementByPosition(NodePtr paraHeader, char paraChar, int paraPosition){
NodePtr p, q;
// Step 1. 搜索给定的位置。
p = paraHeader;
for(int i = 0; i < paraPosition; i ++){
p = p->next;
if(p == NULL){
printf("The position %d is beyond the scope of the list.", paraPosition);
return;
}
}
// Step 2. 创建一个新节点
q = (NodePtr)malloc(sizeof(LNode));
q->data = paraChar;
// Step 3. 链接链表和节点。
printf("linking\r\n");
q->next = p->next;
p->next = q;
}
/**
* 在给定的元素前加入元素。
* @param paraHeader 是链表的头结点。
* @param paraCharInsert 给定插入的char元素。
* @param paraChar 给定的元素。
*/
void insertElementByChar(NodePtr paraHeader, char paraCharInsert, int paraChar){
NodePtr p, q;
int flag = 0;
// Step 1. 搜索给定的元素。
p = paraHeader;
while (p->next != NULL){
p = p->next;
if(p->data == paraChar){
flag = 1;
break;
}
}
if(flag == 0){
printf("The Char %c is not in this list.\r\n", paraChar);
return;
}
// Step 2. 创建一个新节点
q = (NodePtr)malloc(sizeof(LNode));
q->data = paraCharInsert;
// Step 3. 链接链表和节点。
printf("linking\r\n");
q->next = p->next;
p->next = q;
}
/**
* 删除链表中的元素。
* @param paraHeader 是链表的头结点。
* @param paraChar 给定的char元素。
*/
void deleteElement(NodePtr paraHeader, char paraChar){
NodePtr p, q;
p = paraHeader;
while((p->next != NULL) && (p->next->data != paraChar)){
p = p->next;
}
if(p->next == NULL){
printf("Cannot delete %c\r\n", paraChar);
return;
}
q = p->next;
p->next = p->next->next;
free(q);
}
void LinkDestory(NodePtr paraHeader){
NodePtr p;
p = paraHeader;
p->next = NULL;
printf("The list has been destoryed.\r\n");
return;
}
/**
* 功能测试。
*/
void appendInsertDeleteTest(){
// Step 1. 初始化一个空链表。
LinkList tempList = initLinkList();
printList(tempList);
// Step 2. 加入一些字符。
appendElement(tempList, 'H');
appendElement(tempList, 'e');
appendElement(tempList, 'l');
appendElement(tempList, 'l');
appendElement(tempList, 'o');
appendElement(tempList, '!');
printList(tempList);
// Step 3. 删除一些字符(第一次出现的)。
deleteElement(tempList, 'e');
deleteElement(tempList, 'a');
deleteElement(tempList, 'o');
printList(tempList);
// Step 4. 在链表给定位置插入特定元素。
insertElementByPosition(tempList, 'o', 1);
printList(tempList);
// Step 5. 在链表给定元素前插入特定元素。
insertElementByChar(tempList, 'a', 'o');
insertElementByChar(tempList, 'a', 'b');
printList(tempList);
// Step 6. 清空链表
LinkDestory(tempList);
printList(tempList);
}
/**
* 程序入口。
*/
int main(){
appendInsertDeleteTest();
}