02 单链表的建立和查找

#include <iostream>

// 03 单链表的建立、单链表的查找

typedef struct LNode{
    int data;
    LNode *next;
}LNode,*LinkList;

// 1. 含头指针尾插法建立单链表
// (1) 初始化单链表,增加头节点
// (2) 新建一个指针,一开始指向头节点,之后每插入一个元素指向后面的那个节点, 可以把之前插入节点的一小段代码截出来封装

bool step2_insertNext(LNode *pt,int element){     // 在某节点后插入新节点
    if(pt == NULL){
        return false;
    }
    LNode *nod = (LNode*)malloc(sizeof(LNode));
    nod->data = element;
    nod->next = pt->next;
    pt->next = nod;
    return true;
}

bool tail_insert01(LinkList &L){
    L = (LinkList) malloc(sizeof(LNode));
    L->next=NULL;
    LNode *prior = L;
    int d;
    scanf("%d",&d);
    while(d != 1000){
        step2_insertNext(prior,d);
        // prior++; 不连续空间不能使用++
        prior = prior->next;
        scanf("%d",&d);
    }
    return true;
}

// 2. 含头指针头插法建立单链表
// (1) 初始化单链表,增加头节点
// (2) 相较于之前对尾节点使用step2_insertNex,对头节点一直使用此函数
// Tip
// (1) 如果将单链表依次遍历拿出元素,重新按照头插法建立单链表,发现实现了数据逆置效果
// (2) 逆置时可以再新建一个单链表,也可以在此单链表中实现
bool head_insert02(LinkList &L){
    L = (LinkList) malloc(sizeof(LNode));
    L->next=NULL;
    int d;
    scanf("%d",&d);
    while (d != 1000){
        step2_insertNext(L,d);
        scanf("%d",&d);
    }
    return true;
}


// 3. 不含头指针的尾插法
// (1) 初始化单链表,指针指向NULL
// (2) 可以先插入一个元素,再按照带头节点的方法实现

bool tail_insert03(LinkList &L){
    L = (LNode*)malloc(sizeof(LNode));
    int d;
    scanf("%d",&d);
    L->data = d;
    L->next = NULL;
    // 再按照之前的尾插法插入即可
    LNode *prior = L;
    scanf("%d",&d);
    while(d != 1000){
        step2_insertNext(prior,d);
        // prior++; 不连续空间不能使用++
        prior = prior->next;
        scanf("%d",&d);
    }
    return true;
}

// 4. 不含头节点的头插法
// (1) 先插入一个节点
// (2) 在该节点之前再插入节点并设置一个指针始终指向第一个节点,再使用插入那一节中的 在某节点之前插入节点的方法

bool insertPriorNode(LNode *node, LNode *insert){
    if (node == NULL || insert == NULL){
        return false;
    }
    int temp = node->data;
    node->data = insert->data;
    insert->data = temp;

    insert->next = node->next;
    node->next = insert;
    return true;
}

bool head_insert04(LinkList &L){
    L = (LNode*)malloc(sizeof(LNode));
    int d;
    scanf("%d",&d);
    L->data = d;
    L->next = NULL;
    //
    LNode *firstNode = L;
    scanf("%d",&d);
    while (d!=1000){
        LNode *insert = (LNode*) malloc(sizeof(LNode));
        insert->data = d;
        insertPriorNode(firstNode,insert);
        scanf("%d",&d);
    }
    return true;
}

// 5. 含头节点的按位查找
// (1) 在单链表查找那里写过了,不过那里是查找到插入位置(n)的前一位(n-1),这里需要查找到本位(n), 少循环一位,并且这里返回查找到的地址
// Tip:
// (1) 返回地址是为了插入等操作,插入那里需要找到第n-1个元素的地址然后插入,可以直接使用这个函数getEle
LNode * getElem01(LinkList L,int place){
    if(place < 1){
        return NULL;
    }
    int j = 0;
    LNode *pt = L;
    while(j < place && pt != NULL){
        pt = pt->next;
        j++;
    }
//    if(pt == NULL){    // 不写也行,如果pt指向NULL下面依旧会返回NULL
//        return NULL;
//    }
    return pt;
}

// 6. 不含头节点的按位查找
// (1) 和 5 一样,不过需要少循环一次
LNode * getElem02(LinkList L,int place){
    if(place < 1){
        return NULL;
    }
    int j = 0;
    LNode *pt = L;
    while(j < place-1 && pt != NULL){
        pt = pt->next;
        j++;
    }
    return pt;
}

// 7. 含头指针的按值查找
LNode * getElem03(LinkList L, int num){
    LNode *pt = L;
    while(pt != NULL && num != pt->data){
        pt = pt->next;
    }
    return pt;
}

// 8. 不带头指针的按值查找和含头指针一样

// 9. 含头指针返回单链表长度
int getLen01(LinkList L){
    int len = 0;
    LNode *pt = L->next;
    while(pt != NULL){
        pt=pt->next;
        len++;
    }
    return len;
}

// 10. 不含头指针
int getLen02(LinkList L){
    int len = 0;
    LNode *pt = L;
    while(pt != NULL){
        pt=pt->next;
        len++;
    }
    return len;
}

int main() {
//     // 含头指针的头插法和尾插法
//    LinkList L01;
//    tail_insert01(L01);
//    printf("%d  %d\n",getElem01(L01,1)->data, getElem01(L01,2)->data);
//    LinkList L02;
//    head_insert02(L02);
//    printf("%d  %d\n",getElem01(L02,1)->data, getElem01(L02,2)->data);

//=============================================

//     //不含头节点的头插法和尾插法
//    LinkList L03;
//    tail_insert03(L03);
//    LinkList L04;
//    head_insert04(L04);

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值