结构体高级——链表
认识链表
有头链表
- 第一个节点不存放数据
无头链表
- 第一个节点存放了数据
链表基本操作
实现链表基本操作
创建链表
//单一个个体
typedef struct Node
{
int data; //整数为例
struct Node* next;
}NODE,*LPNODE,*LPLIST;
//创建链表的表头
//链表的表头: 就是一个没有初始化数据的结构体变量
LPNODE createHead()
{
LPNODE headNode = (LPNODE)malloc(sizeof(NODE));
//headNode->data=? 有表头链表 表头的数据不做初始化
assert(headNode);
headNode->next = NULL;
return headNode;
}
int main()
{
LPLIST list = createHead();
}
链表的插入
-
创建节点
//创建节点 LPNODE createNode(int data) { LPNODE newNode = (LPNODE)malloc(sizeof(NODE)); assert(newNode); newNode->data = data; newNode->next = NULL; return newNode; }
-
头插法
//插入节点——头插法
void insertByHead(LPLIST list, int data)
{
//把用户的数据变成一个节点
LPNODE newNode = createNode(data);
newNode->next = list->next; //代表变量list->next
list->next = newNode; //断开
}
//打印链表
void printList(LPLIST list)
{
LPNODE pmove = list->next;
while (pmove != NULL)
{
printf("%d\t", pmove->data);
pmove = pmove->next;
}
printf("\n");
}
int main()
{
for (int i = 0; i < 3; i++)
{
//头 0
//头 1 0
//头 2 1 0
insertByHead(list, i);
}
printList(list);
}
-
表尾插入
void insertByTail(LPLIST list, int data) { LPNODE newNode = createNode(data); LPNODE pTailNode = list; while (pTailNode->next != NULL) //list->next list->next->next { pTailNode = pTailNode->next; //pTailNode=list->next->next; list->next->next->next } pTailNode->next = newNode; } int main() { for (int i = 0; i < 3; i++) { insertByTail(list, i); } printList(list); }
-
指定位置插入
void insertByAppoin(LPLIST list, int posData, int data) { //在指定位置的前面插入 //找指定节点: 定义两个相邻的指针去找指定位置 LPNODE preNode = list; LPNODE posNode = list->next; while (posNode!=NULL&&posNode->data != posData) { preNode = posNode; posNode = preNode->next; } //分析退出循环的状态 if (posNode == NULL) { printf("插入失败,没有找到指定位置!\n"); } else { LPNODE newNode = createNode(data); preNode->next = newNode; newNode->next = posNode; } } int main() { insertByAppoin(list, 0, 111); printList(list); }
链表的删除
-
表头删除
void deleteByHead(LPLIST list) { //删除的时候,一定需要考虑是不是存在节点 if (list->next == NULL) { printf("链表为空无法删除!\n"); } else { LPNODE pDeleteNode = list->next; //要删除的节点 list->next = pDeleteNode->next; //交接工作 free(pDeleteNode); pDeleteNode = NULL; } } int main() { deleteByHead(list); printList(list); }
-
表尾删除
void deleteTail(LPLIST list) { LPNODE preTailNode = list; LPNODE pTailNode = list->next; if (pTailNode == NULL) { printf("链表为空无法删除!\n"); return; } while (pTailNode->next != NULL) { preTailNode = pTailNode; pTailNode = preTailNode->next; } free(pTailNode); pTailNode = NULL; preTailNode->next = NULL; } int main() { deleteTail(list); printList(list); }
-
指定位置删除
void deleteAppoin(LPLIST list, int posData) { LPNODE preNode = list; LPNODE posNode = list->next; while (posNode != NULL && posNode->data != posData) { preNode = posNode; posNode = preNode->next; } //分析退出循环的状态 if (posNode == NULL) { printf("删除失败,没有找到指定位置!\n"); } else { //当只有一个节点时候 preNode->next = posNode->next; free(posNode); posNode = NULL; } } int main() { deleteAppoin(list, 111); printList(list); //1 0 0 1 }
-
删除相同元素
//查找函数 LPNODE isLiving(LPLIST list, int posData) { LPNODE pmove = list->next; while (pmove != NULL && pmove->data != posData) { pmove = pmove->next; } return pmove; //返回空 表示没有找到,返回非空表示找到 } void deleteAllAppoin(LPLIST list, int posData) { while (isLiving(list, posData)) { deleteAppoin(list, posData); } } int main() { deleteAllAppoin(list, 0); printList(list); }
字符串的替换
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
//单一个个体
typedef struct Node
{
char data; //整数为例
struct Node* next;
}NODE, * LPNODE, * LPLIST;
//创建链表的表头
//链表的表头: 就是一个没有初始化数据的结构体变量
LPNODE createHead()
{
LPNODE headNode = (LPNODE)malloc(sizeof(NODE));
//headNode->data=? 有表头链表 表头的数据不做初始化
assert(headNode);
headNode->next = NULL;
return headNode;
}
//创建节点
LPNODE createNode(char data)
{
LPNODE newNode = (LPNODE)malloc(sizeof(NODE));
assert(newNode);
newNode->data = data;
newNode->next = NULL;
return newNode;
}
//表尾插入
void insertByTail(LPLIST list, char data)
{
LPNODE newNode = createNode(data);
LPNODE pTailNode = list;
while (pTailNode->next != NULL) //list->next list->next->next
{
pTailNode = pTailNode->next; //pTailNode=list->next->next; list->next->next->next
}
pTailNode->next = newNode;
}
//指定位置插入
void insertByAppoin(LPLIST list, char posData, char data)
{
//在指定位置的前面插入
//找指定节点: 定义两个相邻的指针去找指定位置
LPNODE preNode = list;
LPNODE posNode = list->next;
while (posNode != NULL && posNode->data != posData)
{
preNode = posNode;
posNode = preNode->next;
}
//分析退出循环的状态
if (posNode == NULL)
{
printf("插入失败,没有找到指定位置!\n");
}
else
{
LPNODE newNode = createNode(data);
preNode->next = newNode;
newNode->next = posNode;
}
}
//指定位置删除
void deleteAppoin(LPLIST list, char posData)
{
LPNODE preNode = list;
LPNODE posNode = list->next;
while (posNode != NULL && posNode->data != posData)
{
preNode = posNode;
posNode = preNode->next;
}
//分析退出循环的状态
if (posNode == NULL)
{
printf("删除失败,没有找到指定位置!\n");
}
else
{
//当只有一个节点时候
preNode->next = posNode->next;
free(posNode);
posNode = NULL;
}
}
void insertStr(LPLIST list, const char* str)
{
int i = 0;
while (str[i] != '\0')
{
insertByTail(list, str[i]);
i++;
}
}
void replaceStr(LPLIST list, char x,const char* str)
{
LPLIST insertData = createNode(str[0]); //表头
int i = 1;
while (str[i] != '\0')
{
insertByTail(insertData, str[i]);
i++;
}
//找最后一个节点
LPNODE pTailNode = insertData;
while (pTailNode->next != NULL)
{
pTailNode = pTailNode->next;
}
//pTailNode最后一个节点
LPNODE preNode = list;
LPNODE posNode = list->next;
while (posNode != NULL && posNode->data != x)
{
preNode = posNode;
posNode = preNode->next;
}
if (posNode == NULL)
return;
else
{
preNode->next = insertData;
pTailNode->next = posNode->next;
free(posNode);
posNode = NULL;
}
}
void printList(LPLIST list)
{
LPNODE pmove = list->next;
while (pmove != NULL)
{
putchar(pmove->data);
pmove = pmove->next;
}
printf("\n");
}
int main()
{
char str1[] = "abcdefghijklmn";
puts(str1);
char cNum = 'c';
char str2[100];
printf("请输入替换后的字符串:");
gets_s(str2,100);
puts(str2);
LPLIST strList = createHead();
insertStr(strList, str1);
replaceStr(strList, 'c', str2);
printList(strList);
return 0;
}