线性表的链式存储(传统模式)

    科技2022-08-05  110

    为了便于自己理解,画了单链表的结构示意图,如下:

     

    插入链表示意图如下:

    删除结点示意图:

    下面是对应的代码实现

    #include<iostream> using namespace std; /*链表的结构写出来*/ typedef struct Node { int data;//数据域 struct Node *next;//指针域 }; //链表的抽象方法有哪些 //创建一个链表 现在默认创建带头节点的链表 //通过画图看下链表的结构,以及头指针和头节点的概念 //1.初始化一个链表,得到一个头指针 void creatlist(struct Node **p) { struct Node *tmp = (struct Node *)malloc(sizeof(Node)); tmp->data = 0;//头节点可以不赋值 tmp->next = NULL; *p=tmp; } //2.向链表中插入一个元素 画出示意图 void insertlist(struct Node *list, int i, int e) { int j=0;//作为计数器进行使用 //先用while循环实现 struct Node *tmp= list; while (tmp != NULL&&j < i) { tmp = tmp->next; j++; } if (j>i || tmp == NULL)//这个j>i是个习惯的写法,不会出现 { return; } struct Node *S = (struct Node *)malloc(sizeof(Node)); S->data = e; S->next = tmp->next; tmp->next = S; } //3.链表的遍历 void traverselist(struct Node *list) { struct Node *tmp = list; while (tmp->next != NULL) { printf("value is[%d]\n", tmp->next->data); tmp = tmp->next; } } //4.删除链表中的元素 void deletelist(struct Node *list, int i, int *e) { //删除元素,并且取出元素的值 if (list == NULL) { return; } int j = 0;//作为计数器进行使用 struct Node *cur = list; while (cur != NULL&&j < i) { cur = cur->next; ++j; } if (cur == NULL || j>i) { return; } //核心算法 *e = cur->next->data; struct Node *temp=cur->next; cur->next = cur->next->next; free(temp); temp=NULL; return; } //获取链表中的某一个元素 int getelement(struct Node *list, int i, int *e) { if (list == NULL) { return -1; } int j = 0;//作为计数器进行使用 struct Node *cur = list; while (cur != NULL&&j < i) { cur = cur->next; ++j; } if (cur == NULL || j>i) { return -2; } //核心算法 *e = cur->next->data; return 0; } //5.销毁链表,要传二级指针或者一级指针的引用 void destroylist(struct Node **list) { int a = 6; struct Node *p = (*list)->next;//头指针 struct Node *q = NULL; //开始释放结点的内存 while (p!= NULL) { q = p->next; free(p); p = q; } free(*list); *list = NULL; } int main() { //测试程序: struct Node *head = NULL; creatlist(&head); insertlist(head,0,1); insertlist(head,0,2); insertlist(head,0,3); insertlist(head,0,4); //遍历链表 traverselist(head); int a; deletelist(head,3,&a); traverselist(head); getelement(head, 0, &a); printf("getelement 0[%d]\n",a); destroylist(&head); if (head == NULL) { printf("free success\n"); } return 0; }

    代码的输出如下:

    这里需要解释两点

    1.如题目所说为啥叫线性表的链式存储的传统模式呢,这个就是写代码练习,因为这个结构的数据和指针域混在了一起,

    即使可以用宏来定义数据域的类型,但是这种耦合在一起不方便使用,也就是没有实现业务逻辑和 链表结构的相互分离。

    如果进行分离,看下面的文章会继续写:

    2.对于链表的api函数,啥时候用二级指针,啥时候用一级指针,总结一句话

    用n指针(形参)改变n-1指针(实参)的值

    也就是如果你需要对一个指针本身进行写操作,那就要传多一级的指针,如果只是进行读操作,就只传本级指针就可以了。

    所以创建链表,销毁链表都需要传二级指针(或者c++里传一级指针的引用也可以),因为我们要改变头指针的指向,其他的传一级指针就可以搞定,但是你非要也传二级指针也没有问题的。

    Processed: 0.022, SQL: 8