有关多种(单向,双向,循环)链表的操作----初始化,插入,输出,删除,头(尾)插法
程序员文章站
2022-04-10 23:45:51
...
代码以功能排布,相同的功能,不同种类的链表放在一块便于对比
#include"stdio.h"
#include"stdlib.h"
typedef struct Node {
int data;
struct Node* Next;
}*PList;
typedef struct DNode {
int data;
struct DNode* Next;
struct DNode* Prior;
}*DList; //双向循环链表
typedef struct CNode {
int data;
struct CNode* Next;
}*CList; //单向循环链表
/*输出组*/
void Print(struct Node* p) {
printf("单向链输出: ");
p = p->Next;
while (p) {
printf("%d ", p->data);
p = p->Next;
}
printf("\n");
}
void Print_D(struct DNode* P) {
printf("双向链输出: ");
struct DNode* p = P->Next;
while (p != P) {
printf("%d ", p->data);
p = p->Next;
}
printf("\n");
}
void Print_CH(struct CNode* P) {
printf("循环链输出(头指针): ");
struct CNode* p = P->Next;
while (p != P) {
printf("%d ", p->data);
p = p->Next;
}
printf("\n");
}
void Print_CE(struct CNode* p) { //p指向链表的尾部
printf("循环链输出(尾指针): ");
struct CNode* c = p->Next->Next;
while (c != p->Next) { //c指向头结点的时候结束
printf("%d ", c->data);
c = c->Next;
}
printf("\n");
}
/*初始化组*/
int Init(PList* P) {
*P = (PList)malloc(sizeof(struct Node));
if (!*P) {
printf("failed to initialize\n");
return 1;
}
(*P)->Next = NULL; //一定要记住赋初值
return 0;
}
int DInit(DList* P) {
*P = (DList)malloc(sizeof(struct DNode));
if (!*P) {
printf("failed to initialize\n");
return 1;
}
(*P)->Next = *P;
(*P)->Prior = *P;
return 0;
}
int CInit(CList* P) {
*P = (CList)malloc(sizeof(struct CNode));
if (!*P) {
printf("failed to initialize\n");
return 1;
}
(*P)->Next = *P;
return 0;
}
/*插入 从1到n都可插 插到第i个前*/
int ListInsert(PList* P, int i, int e) {
PList p = *P; int j = 0;
while (p && j < i - 1) { //p要指向i前一个结点
p = p->Next; j++;
}
if (i - 1 < j || !p) {
printf("i is error\n");
return 0;
}
PList s = (PList)malloc(sizeof(struct Node));
s->data = e;
s->Next = p->Next;
p->Next = s;
return 1;
}
int DListInsert(DList* P, int i, int e) {
DList p = *P; int j = 0;
while (p->Next != *P && j < i - 1) { //p指向i前一个结点 注意第一次时p指向头结点,需要进入while循环,之后的条件不可以以p指向头结点为退出条件
//因为指向i这个结点时会有麻烦,当在最后一个插入时,需要再次指向头节点,所以while条件就会麻烦。
p = p->Next; j++;
}
if (i - 1 != j) {
printf("i is error\n");
return 0;
}
DList s = (DList)malloc(sizeof(struct DNode));
s->data = e;
s->Next = p->Next;
p->Next->Prior = s;
p->Next = s;
s->Prior = p;
return 1;
}
int CListInsert(CList* P, int i, int e) {
CList p = *P; int j = 0;
while (p->Next != *P && j < i - 1) { //p指向i前一个结点
p = p->Next; j++;
}
if (i - 1 != j) {
printf("i is error\n");
return 0;
}
CList s = (CList)malloc(sizeof(struct CNode));
s->data = e;
s->Next = p->Next;
p->Next = s;
return 1;
}
//头插法
int CHListInsert(CList* P, int e) {
CList H = (CList)malloc(sizeof(struct CNode));
if (!H) {
return 0;
}
H->data = e;
H->Next = (*P)->Next;
(*P)->Next = H;
return 1;
}
//尾插法
int CEListInsert(CList* P, int e) {
CList E = (CList)malloc(sizeof(struct CNode));
if (!E) {
return 0;
}
E->data = e;
E->Next = (*P)->Next;
(*P)->Next = E;
*P = E;
return 1;
}
/*删除组*/
int DeleList(PList* P, int i, int* e) {
PList p = *P; int j = 0; //p指向i前一个结点且要保证第i个结点存在
while (p->Next != NULL && j < i - 1) {
p = p->Next; j++;
}
if (i < j || p->Next == NULL) {
return 0;
}
PList d = p->Next;
*e = d->data;
p->Next = d->Next;
free(d);
return 1;
}
int DeleDList(DList* P, int i, int* e) {
DList p = (*P)->Next; int j = 1; //让p指向第i个结点
while (p != *P && j < i) {
p = p->Next; j++;
}
if (i != j || p == *P) {
return 0;
}
*e = p->data;
p->Next->Prior = p->Prior;
p->Prior->Next = p->Next;
free(p);
return 0;
}
int DeleCList(CList* P, int i, int* e) {
CList p = *P; int j = 0; //p指向i前一个 要保证i个结点存在
while (p->Next != *P && j < i - 1) {
p = p->Next; j++;
}
if (p->Next == *P || i < j) {
return 0;
}
CList d = p->Next;
*e = d->data;
p->Next = d->Next;
}
/*测试*/
int main() {
PList plist; DList dlist; CList clist;
Init(&plist); DInit(&dlist); CInit(&clist);
Print(plist);
Print_D(dlist);
Print_CH(clist);
printf("\n");
int elem[] = {1,2,3,4,5};
for (int i = 0; i < 5; i++) { //有效插入
ListInsert(&plist, i+1, elem[i]);
DListInsert(&dlist, i+1, elem[i]);
CListInsert(&clist, i+1, elem[i]);
}
Print(plist);
Print_D(dlist);
Print_CH(clist);
printf("\n");
int err = 9;
//错误插入
ListInsert(&plist, 7, err);
DListInsert(&dlist, 7, err);
CListInsert(&clist, 7, err);
ListInsert(&plist, 0, err);
DListInsert(&dlist, 0, err);
CListInsert(&clist, 0, err);
Print(plist);
Print_D(dlist);
Print_CH(clist);
printf("\n 尾插法: \n");
//循环链表的尾插法
CList c;
CInit(&c);
for (int i = 0; i < 7; i++) {
CEListInsert(&c, i);
}
Print_CE(c);
printf("\n 头插法: \n");
//循环链表的头插法
CList h;
CInit(&h);
for (int i = 0; i < 7; i++) {
CHListInsert(&h, i);
}
Print_CH(h);
printf("\n");
}
这段代码实现了一些链表的基础操作
如果还需要什么功能,可以在评论区内留言
上一篇: python 删除csv文件的某几列,并写入新的csv文件
下一篇: 修改confirm样式