【数据结构学习】二、链表和二叉树

前言

写个makefile并且加入asan用来检查内存相关的内容。直接在此目录下make即可。因为我老是控制不好申请和释放。

SRC = $(wildcard *.cpp)
OBJ = $(patsubst %.cpp, %.o, $(SRC))

ALL: test.out

test.out: $(OBJ)
    g++ -fsanitize=address $< -lm -o $@ -l pthread

$(OBJ): $(SRC)
    g++ -fsanitize=address -c $<  -lm -o $@ -l pthread

1 链表

1.1 概念

链表是一种物理存储单元上非连续、非顺序的存储结构数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

------百度词条

关于链表的概念就不介绍了,直接看图实战。

由上图可以知道链表头不存数据,非空链表直接指向下一个节点,通过这样串连在一起。

定义节点的结构体

struct Node
{
    int val;
    Node* next = nullptr;
};

对应的第一个节点赋值和申请

    // listNode* p1 = nullptr;
    // p1 = new listNode;
    Node* p1 = new Node; //上述两行等价与这一行
    p1->val = 2;
    p1->next = nullptr;

    Node* p2 = new Node;
    p2->val = 4;
    p2->next = nullptr;

然后把两个节点串联起来。

p1->next  = p2;

看串连是否成功,写一个打印链表的函数。我这边是把头节点也打印出来,方便理解。

void printList(Node* list)
{
    int i  = 0;
    while (list != nullptr)
    {
        cout << "[" << i  << "]:"<< list->val << " ";
        list = list->next;
        i++;
    }
    cout << endl;
}

直接打印

printList(p1);

输出终端结果为:表示串联成功,注意,头节点一般不存储数据。但是它理论是可以存储数据的。

[0]:2 [1]:4

1.2 LIST基础操作

  • 尾插

    单向链表最常用的插入数据是尾插。

    尾插的工作原理是遍历到链表尾部的nullptr然后在这个位置把对应的node插进去

    直接看代码实现.插入的时候注意下是list->next的时候为null的判断。

    void pushBack(Node* list,int val)
    {
        Node* cur = p;
        Node* newNode = new Node;
        newNode->val = val;
        while(cur->next!=nullptr)
        {
            cur = cur->next;
        }
        cur->next = newNode;
    }
    

    测试demo为

    int main()
    {
        Node* p1 = new Node;
        p1->val = 1;
    
        pushBack(p1,2);
        pushBack(p1,3);
        pushBack(p1,4);
        printList(p1);
    
        return 0;
    }
    

打印输出的结果为

[0]:1 [1]:2 
[0]:1 [1]:2 [2]:3 
[0]:1 [1]:2 [2]:3 [3]:4 
[0]:1 [1]:2 [2]:3 [3]:4 
  • 头插入

    头插顾名思义就是在链表的头部插入数据,将新节点插入到头节点后面即可。

void pushFront(Node* p,int val)
{

if(p == nullptr)
{
p = new Node;
p ->val = val;
p ->next = nullptr;
}
else
{
Node* newNode = new Node;
newNode->val = val;
newNode->next = p->next;
p->next = newNode;
}
}
  • 求链表长度

链表长度不算头节点。正常的从头开始遍历计数即可。

int lensList(Node* p)
{
    int count = 0;
    while (p->next!=nullptr)
    {
        count++;
        p = p->next;
    }
    return count;
}
  • 链表的逆序

void reverse(Node* head)
{
    if ((head->next == nullptr )||(head->next->next == nullptr))
    {
        return;
    }
    else
    {
        Node* pCur = head->next;
        Node* pNext = pCur->next;
        Node* pre = nullptr;
        while (pNext)
        {
            pCur->next = pre;
            pre = pCur;
            pCur = pNext;
            pNext = pCur->next;
        }
        pCur->next = pre;
        head->next = pCur;
        return;
    }
}
  • 删除链表:某个节点作为暂存节点去存,然后去不停的删这个暂存的节点即可。

    void deleteList(Node* head)
    {
        while (head)
        {
            Node* del = head;
            head = head->next;
            delete del;
        }
        head = nullptr;
        delete head;
    }
    

2 二插树

2.1 概念

struct binaryTree
{
    int data;
    binaryTree* left;
    binaryTree* right;
};

前序遍历二叉树:先输出根节点,再输出左孩子,之后输出右孩子

void preOrder(binaryTree* node)
{
    if(node)
    {
        cout << node->data << " ";
        preOrder(node->left);
        preOrder(node->right);
    }
}

中序遍历二叉树:先输出左孩子,再输出根节点,之后输出右孩子。

void midOrder(binaryTree* node)
{
    if(node)
    {
        midOrder(node->left);
        cout << node->data << " ";
        midOrder(node->right);
    }
}

后序遍历二叉树:先输出左孩子,再输出右还在,在输出根节点

void postOrder(binaryTree* node)
{
    if(node)
    {
        postOrder(node->left);
        postOrder(node->right);
        cout << node->data << " ";
    }
}

前序,中序,后序遍历是根据根节点的位置来定的。

相关demo如下

int main()
{
    binaryTree* t1 = new binaryTree;
    t1->data = 1;

    binaryTree* t2 = new binaryTree;
    t2->data = 2;

    binaryTree* t3 = new binaryTree;
    t3->data = 3;

    t1->left = t2;
    t1->right = t3;

    preOrder(t1);
    cout << endl;
    midOrder(t1);
    cout << endl;
    postOrder(t1);
    cout << endl;

}

猜你喜欢

转载自blog.csdn.net/qq_38753749/article/details/128720086