Data Structure 初学链表(ADT实现)

通过c语言实现最原始的链表(输入的链表指定输入的个数,至于无限输入请往下翻),顺便复习一下c语言的语法。

①按照ADT的实现,把链表的实现划分为许多功能。

#include<stdio.h>
#include<stdlib.h>
typedef struct LNode{
    int elem;
    struct LNode *next;
}LNode, *LinkedList;
void IntiList(LinkedList *);//初始化链表
int LocateElem(LinkedList ,int target);//从链表中寻找与target相等的数字,并返回该数字的位序
void DestroyList(LinkedList *);//释放链表所占用的内存

其中typedef语句中的*LinkedList是什么意思呢?
其实就是struct LNode *等价于LinkedList。
headNode是头指针,指向头结点,头结点没有设置数据域,头结点接下来是第一个有数据域的节点。

②接下来给出程序的主体

int main(void){
    LinkedList headNode;
    headNode = (LinkedList)malloc(sizeof(LNode));
    IntiList(headNode);//传递指针
    int index,target;
    scanf("%d",&target);
    index = LocateElem(headNode, target);
    printf("%d",index);
    DestroyList(&headNode);//传递指针的指针
    return 0;
}

③下面重点看IntiList 函数的实现
我先贴出一开始我错误的做法:

void IntiList(LinkedList L){
    int num,i;
    LinkedList temp = L;
    scanf("%d",&num);//决定链表有多少个节点
    for(i=0;i<num;i++){
        temp = temp->next;
        printf("%p\n",temp);
        temp = (LinkedList)malloc(sizeof(LNode));
        printf("%p\n",temp);
        scanf("%d",&temp->elem);
    }
    temp->next = NULL;
    printf("%d",L->next->elem);//没有输出数字而是输出内存地址
}

以上函数的问题出错的地方恰好就是for循环中两个printf之间的语句。因为malloc函数会分配一个全新的地址给temp,这个新的地址把temp->next这一个与之前的strcut有联系的地址给覆盖掉了,也就是说,前后的printf输出的temp的内存地址是不同的,自然新的地址与之前的struct没有联系。

那么如何解决这样的问题呢?
我们可以先malloc一个新的地址然后再把地址赋值给temp->next就可以了。
实现代码:

void IntiList(LinkedList L){
     int num,i;
     LinkedList prev = L;
     LinkedList current;
     scanf("%d",&num);//决定链表有多少个节点
     for(i=0;i<num;i++){
        current = (LinkedList)malloc(sizeof(LNode));
        scanf("%d",&current->elem);
        prev->next = current;
        prev = current;
     }
     current->next = NULL;
}

④LocateElem以及DestroyList函数的实现:

int LocateElem(LinkedList L, int target){
    LinkedList temp = L;
    int i = 0;
    while(temp->next != NULL){
        temp = temp->next;
        i++;
        if(temp->elem == target){
            break;
        }
    }
    return i;
}

void DestroyList(LinkedList *L){
    LinkedList temp;
    while(*L){
        temp = (*L)->next;
        free(*L);
        *L = temp;
    }
}

⑤最后说一下c语言的函数传递参数

c语言是按值传递的

也就是说在函数传递的时候,对传递的参数进行了浅复制。
举个例子

void a(int b);
int main(void){
    int c = 1;
    a(c);
    return 0;
}

void a(int b){
}

也就是说在main函数中的c的指针与a函数的中b的指针是不一样的,如果想在a函数中修改c的值并体现在main函数中则必须传递c的指针。
所以,也就是说,如果我们想修改指针的地址时,必须传递指针的指针。

To be continued.

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页