目录
1.循环单链表的初始化
2.循环双链表
3. 静态链表
(1)静态链表的初始化
(2)静态链表的插入
1.循环单链表的初始化
typedef int ElemType;
typedef struct LNode{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;
bool InitList(LinkList &L)
{
    L=(LNode*)malloc(sizeof(LNode));//建立一个空表分配一个头结点
    if(L==NULL)
        return false;
    L->next=L;//头结点next指向头结点
    return true;
}
//判断循环单链表是否为空
bool Empty(LinkList L)
{
    if(L->next==L)
        return ture;
    else
        return false;
}
//判断结点p是否为循环单链表的表尾结点
bool isTail(LinkList L,LNode *p)
{
    if(p->next==L)
        return true;
    else
        return false;
} 
L->next=L;
2.循环双链表

typedef int ElemType;
typedef struct DNode{
    ElemType data;
    struct DNode *prior,*next;
}
bool InitDLinkList(DLinkList &L)
{
    L=(DNode*)malloc(sizeof(DNode));
    if(L==NULL)
        return false;
    L->prior=L;
    L->next=L;
    return true;
}
//判断循环双链表是否为空表
bool Empty(DLinkList L)
{
    if(L->next==L)
        return true;
    else
        return false;
}
//判断结点p是否为循环双链表的表尾结点
bool isTail(DLinkList L,DNode *p)
{
    if(p->next==L)
        return true;
    else
        return false;
}
void testLinkList()
{
    DLinkList L;
    InitDLinkList(L);
    
} 
对于普通双链表的插入操作而言
s->next=p->next;
p->next->prior=s;//是有错误的
s->prior=p;
p->next=s;
但是对于循环双链表而言是正确的
对于普通链表的删除操作而言
p->next=q->next;
q->next->prior=p;//要删除的结点q是最后一个结点,这里就会存在问题
free(q);
但是对循环双链表而言是正确的
3. 静态链表

单链表和静态链表的区别
1.单链表的指针是指明了具体的内存地址,静态链表的游标指的是下一个元素的数组下标,例如0号结点,他的游标是2,那么第一个元素就是下标为2的元素,即1
2.单链表的表尾元素是指向NULL的,而静态链表中最后一个结点的游标可以设为-1
3.如图所示,如果每个数据元素4B,每个游标4B(每个结点是8B),e1的地址就是(0号结点的地址)+8*2(要寻找的结点的数组下标)
#define MaxSize 10
typedef int ElemType;
struct Node{
    ElemType data;
    int next;
};
void testLinkList(){
    struct Node a[MaxSize];  //a是一个Node型数组
}
//也可以写为
typedef struct{
    ElemType data;
    int next;
}SLinkList[MaxSize];
    
void testLinkList(){
    SLinkList a;//a是一个数组,这个数组有10个元素  
//这里a是一个静态链表
}
 
测试代码
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 10
struct Node{
	int data;
	int next;
};
typedef struct{
	int data;
	int next;
	
}SLinkList[MaxSize];
int main()
{
	struct Node x;
	printf("sizeX=%d\n",sizeof(x));
	struct Node a[MaxSize];
	printf("sizeA=%d\n",sizeof(a));
	SLinkList b;
	printf("sizeB=%d\n",sizeof(b));
	return 0;
} 
结果

可以看到
struct Node a[MaxSize]等价于LinkList a
(1)静态链表的初始化
对于单链表而言,初始化就是将结点指向NULL
所以对于静态链表的初始化就是将头结点指向-1
(2)静态链表的插入
①找到一个空的结点,存入数据元素
②从头结点出发找到位序为i-1的结点
③修改新节点的next
④修改i-1的结点的next
举个例子
#include <stdio.h>
#define MaxSize 100
typedef struct {
  int data;
  int next;
} SLinkList[MaxSize];
// 初始化静态链表
void InitList(SLinkList list) {
  for (int i = 0; i < MaxSize; i++) {
    list[i].next = -1;  // 初始化指针域为-1,表示空节点
  }
}
// 插入元素到静态链表的末尾
void Insert(SLinkList list, int data) {
  int index = 0;
  while (list[index].next != -1) {
    index = list[index].next;  // 找到最后一个节点
  }
  
  // 创建新节点
  list[index].next = index + 1;  // 设置最后一个节点的指针指向新节点
  list[index + 1].data = data;  // 设置新节点的数据域
  list[index + 1].next = -1;  // 新节点的指针域设置为-1
}
// 打印静态链表
void PrintList(SLinkList list) {
  int index = list[0].next;
  while (index != -1) {
    printf("%d ", list[index].data);
    index = list[index].next;
  }
  printf("\n");
}
int main() {
  SLinkList list;
  InitList(list);
  // 在静态链表中插入元素
  Insert(list, 10);
  Insert(list, 20);
  Insert(list, 30);
  
  // 打印静态链表
  PrintList(list);
  return 0;
} 
静态链表的优点
增删操作不需要大量的移动元素
静态链表的缺点
不能随机存取,只能从头结点开始一次往后查找
容量固定不变
如有错误请大佬们不吝赐教!!💖💖💖












![[C++] 迭代器失效示例](https://img-blog.csdnimg.cn/0722629f7a69499599216f0327597092.png)









