2.2单链表的实现及收获

2.2 单链表的具体内容

首先,单链表作为线性表的一种实现方式,拥有特质——一对一,用结构体和指针的方式去实现,通过指针移动的方式可以遍历整个链表。相较于顺序表,链表可以更有效的利用空间,也可以防止数据域中的元素泄露。但是如果其中的某一个的指针丢失,会导致后续的数据丢失(顺序表就不需要考虑这些意外)

2.2.1 单链表的代码及具体操作

2.2.1.1  单链表的建立及初始化

typedef struct LinkNode{
    char data;
    struct LinkNode *next;
} LNode, *LinkList, *NodePtr;

LinkList initLinkList(){
    NodePtr tempHeader = (NodePtr)malloc(sizeof(LNode));
    tempHeader->data = '\0';
    tempHeader->next = NULL;
    return tempHeader;
}// Of initLinkList

2.2.1.2 单链表的打印操作

void printList(NodePtr paraHeader){
    NodePtr p = paraHeader->next;
    while (p != NULL) {
        printf("%c", p->data);
        p = p->next;
    }// Of while
    printf("\r\n");
}// Of printList

2.2.1.3 单链表的添加操作

void appendElement(NodePtr paraHeader, char paraChar){
    NodePtr p, q;

    // Step 1. Construct a new node
    q = (NodePtr)malloc(sizeof(LNode));
    q->data = paraChar;
    q->next = NULL;

    // Step 2. Search to the tail
    p = paraHeader;
    while (p->next != NULL) {
        p = p->next;
    }// Of while

    // Step 3. Now add
    p->next = q;
}// Of appendElement

2.2.1.4 单链表的节点插入操作

void insertElement(NodePtr paraHeader, char paraChar, int paraPosition){
    NodePtr p, q;

    // Step 1. Search to the position.
    p = paraHeader;
    for (int i = 0; i < paraPosition; i ++) {
        p = p->next;
        if (p == NULL) {
            printf("The position %d is beyond the scope of the list.", paraPosition);
            return;
        }// Of if
    } // Of for i

2.2.1.5 单链表的删除操作

void deleteElement(NodePtr paraHeader, char paraChar){
    NodePtr p, q;
    p = paraHeader;
    while ((p->next != NULL) && (p->next->data != paraChar)){
        p = p->next;
    }// Of while

    if (p->next == NULL) {
        printf("Cannot delete %c\r\n", paraChar);
        return;
    }// Of if

    q = p->next;
    p->next = p->next->next;
    free(q);
}// Of deleteElement

2.2.1.6 单链表的查找操作(此处返回的是查找节点的地址)

NodePtr findElement(LinkList templist, char Find ){
    NodePtr p = NULL,q = NULL;
    p = templist;
    
    while ((p->next != NULL) && (p->next->data != Find) ){
        p = p->next;
    }
    if(p->next == NULL){
        printf("This list don't have this element\r\n");
        return NULL;
    }
    q = p;
    return q;
}// Of findElement

2.2.3程序的测试和运行

此处先展示二段测试代码

1.appendInsertDeleteTest(用于测试增 插 删)

void appendInsertDeleteTest(){
    // Step 1. Initialize an empty list.
    LinkList tempList = initLinkList();
    printList(tempList);

    // Step 2. Add some characters.
    appendElement(tempList, 'H');
    appendElement(tempList, 'e');
    appendElement(tempList, 'l');
    appendElement(tempList, 'l');
    appendElement(tempList, 'o');
    appendElement(tempList, '!');
    printList(tempList);

    // Step 3. Delete some characters (the first occurrence).
    deleteElement(tempList, 'e');
    deleteElement(tempList, 'a');
    deleteElement(tempList, 'o');
    printList(tempList);

    // Step 4. Insert to a given position.
    insertElement(tempList, 'o', 1);
    printList(tempList);

    insertElement(tempList,' ',0);
    insertElement(tempList,'u',0);
    insertElement(tempList,'o',0);
    insertElement(tempList,'y',0);

    printList(tempList);

}// Of appendInsertDeleteTest

运行结果

 2.findElementTest

void findElementTest(){
    //Step 1 struct a list
    LinkList tempList = initLinkList();
    printList(tempList);
    char findE = 0 ;
    LinkList  FindPtr = 0;
    //Step 2 add some elemwent

    appendElement(tempList, 'H');
    appendElement(tempList, 'e');
    appendElement(tempList, 'l');
    appendElement(tempList, 'l');
    appendElement(tempList, 'o');
    appendElement(tempList, '!');
    printList(tempList);


    //Step 3 putinto the element,return the address

    printf("Please tpye in the char \r\n ");
    scanf("%c",&findE);

    FindPtr=findElement(tempList , findE);

    //Step 4 check the result

    printf("%p",FindPtr);
}

运行结果

 2.2.4收获及总结

1.在闵老师的地址打印测试程序中,我发现链表节点的指针(ListNode)和 data域的指针(LinkList->data)的地址是相同的,而指针域的地址(LinkList->next)相差了8个byte。这意味着前两者是储存在一起的。(不会是联合类型吧?虽然我不懂)

2.对链表的学习,让我更加意识到组织数据储存方式的重要性,不同的储存方式,不仅在计算机的内存中有区别,同时也有对应的实际意义,比如链表不易造成数据泄露,从本质上认识数据的储存方式,能增长有用的逻辑思维。

3.我现在能或多或少地模仿闵老师的代码写法了,虽然到不了那么简洁,但也是初具雏形。在仔细地观察过闵老师的代码后,很多现阶段的逻辑思维也是我模仿不出来的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值