- 什么是链表,链表的分类
链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的.
链表总共可以分为八种.
- 链表带头结点和不带头结点的区别
带头节点:使链表插入和删除第一个元素更加方便,统一空表和非空表的处理
若使用头结点,无论链表表是否为空,头指针都指向头结点,也就是LNode类型,对于空表和非空表的操作是一致的。
若不使用头结点,当表非空时,头指针指向第1个结点的地址,即LNode类型,但是对于空表,头指针指向的是NULL,此时空表和非空表的操作是不一致的。 - 单链表的部分基本操作及代码
部分基本操作:
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <malloc.h>
typedef int SDataType;
typedef struct SListNode {
SDataType data;
struct SListNode* Next;
}Node,*PNode;
typedef struct SList {
PNode pHead;
}SList,*PSList;
// 链表的初始化
void SListInit(PSList s);
// 在链表s最后一个节点后插入值为data的节点
void SListPushBack(PSList s, SDataType data);
// 删除链表s最后一个节点
void SListPopBack(PSList s);
// 在链表s第一个节点前插入值为data的节点
void SListPushFront(PSList s, SDataType data);
// 删除链表s的第一个节点
void SListPopFront(PSList s);
// 在链表的pos位置后插入值为data的节点
void SListInsert(PNode pos, SDataType data);
// 删除链表s中pos位置的节点
void SListErase(PSList s, PNode pos);
// 在链表中查找值为data的节点,找到返回该节点的地址,否则返回NULL
PNode SListFind(PSList s, SDataType data);
// 获取链表中有效节点的个数
size_t SListSize(PSList s);
// 检测链表是否为空
int SListEmpty(PSList s);
// 将链表中有效节点清空
void SListClear(PSList s);
// 销毁链表
void SListDestroy(PSList s);
//打印链表
void SListPrintf(PSList s);
程序代码:
#include "Slist.h"
void SListInit(PSList s) {
assert(s);
s->pHead = NULL;
}
void SListPrintf(PSList s) {
assert(s);
PNode pCur = s->pHead;
while (pCur) {
printf("%d", pCur->data);
pCur = pCur->Next;
}
printf("NULL\n");
}
PNode BuySListNode() {
PNode PNewNode = (PNode)malloc(sizeof(Node));
if (PNewNode == NULL) {
assert(0);
return NULL;
}
return PNewNode;
}
void SListPushBack(PSList s,SDataType data) {
assert(s);
PNode pCur = s->pHead;
PNode PNewNode = BuySListNode();
if (s->pHead == NULL) {
s->pHead = PNewNode;
s->pHead->data = data;
s->pHead->Next = NULL;
}
else {
while (pCur->Next) {
pCur = pCur->Next;
}
pCur->Next = PNewNode;
PNewNode->data = data;
PNewNode->Next = NULL;
}
}
void SListPushFront(PSList s, SDataType data) {
assert(s);
PNode PNewNode = BuySListNode();
if (s->pHead != NULL) {
PNewNode->data = data;
PNewNode->Next = s->pHead;
s->pHead = PNewNode;
}
else{
PNewNode->data = data;
PNewNode->Next = NULL;
s->pHead = PNewNode;
}
}
void SListPopBack(PSList s) {
assert(s);
PNode pCur = s->pHead;
if (s->pHead) {
if (s->pHead->Next == NULL) {
free(s->pHead);
s->pHead = NULL;
return;
}
while (pCur->Next->Next) {
pCur = pCur->Next;
}
free(pCur->Next);
pCur->Next = NULL;
}
else {
return;
}
}
void SListPopFront(PSList s) {
assert(s);
PNode pCur = s->pHead;
if (pCur) {
s->pHead = s->pHead->Next;
free(pCur);
}
else {
return;
}
}
void SListInsert(PNode pos, SDataType data) {
if (pos == NULL) {
return;
}
PNode pNewNode = (PNode)malloc(sizeof(Node));
pNewNode->data = data;
pNewNode->Next = pos->Next;
pos->Next = pNewNode;
}
void SListErase(PSList s, PNode pos) {
assert(s);
if (pos == NULL) {
return;
}
if (s->pHead == NULL) {
return;
}
while (s->pHead != pos&&s->pHead->Next!= NULL) {
s->pHead = s->pHead->Next;
}
if (s->pHead == pos) {
s->pHead = pos->Next;
free(pos);
}
}
PNode SListFind(PSList s,SDataType data) {
assert(s);
while(s->pHead && s->pHead->data != data) {
s->pHead = s->pHead->Next;
}
if (s->pHead->data == data) {
return s->pHead;
}
return NULL;
}
size_t SListSize(PSList s) {
assert(s);
size_t count = 0;
while (s->pHead) {
s->pHead = s->pHead->Next;
++count;
}
return count;
}
int SListEmpty(PSList s) {
assert(s);
if (s->pHead == NULL) {
return 0;
}
else {
return 1;
}
}
void SListClear(PSList s) {
assert(s);
if (s->pHead == NULL) {
return;
}
s->pHead = NULL;
}
//不带头节点与清空相同
void SListDestroy(PSList s) {
}
int main() {
SList s;
SListInit(&s);
system("pause");
return 0;
}