C语言进阶C语言C++

【练习】链表及链表面试题(一)入门

2017-06-15  本文已影响139人  pangdaaa

巩固一下基础,我重新写了一下无头节点单链表及链表面试题。我会分为入门,基础,进阶三章进行总结,点击以下蓝色字直接跳转对应章节。

链表及链表面试题(一)入门
链表面试题(二)基础
链表面试题(三)进阶

** 首先看一下顺序表和链表的优缺点,分别在什么场景下使用? **

从它们的存储优缺点来看,各自有各自的** 使用场景 **,比如:频繁的查找却很少的插入和删除操作可以用顺序表存储,如果频繁的插入和删除操作很少的查询就可以使用链表存储;
查看原文

源代码:

list.h

//list.h

#ifndef __LIST_H__
#define __LIST_H__

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

typedef int DataType;

typedef struct Node
{
    DataType data;
    struct Node* next;

}Node, *pNode, *pList;

//init list
void InitList(pList* pplist);
pNode BuyNode(DataType d);

//pop/push
void PushBack(pList* pplist, DataType d);
void PopBack(pList* pplist);
void PushFront(pList* pplist, DataType d);
void PopFront(pList* pplist);

int getsize(pList list);
void PrintList(pList plist);

pNode Find(pList plist, DataType d);
void Remove(pList* pplist, DataType d);
void RemoveAll(pList* pplist, DataType d);
void Insert(pList* pplist, pNode pos, DataType d);
void Erase(pList* pplist, pNode pos);

void ReverseList(pList* pplist);
void BubbleSort(pList* pplist);

void DestroyList(pList* pplist);

#endif // !__LIST_H__
//list.c
#include "list.h"

void InitList(pList* pplist)
{
    assert(pplist);
    *pplist = NULL;
}

pNode BuyNode(DataType d)
{
    pNode pnode = (pNode)malloc(sizeof(Node));
    if (pnode == NULL)
    {
        perror("malloc error");
        return -1;
    }
    pnode->data = d;
    pnode->next = NULL;

    return pnode;
}

void PushBack(pList* pplist, DataType d)
{
    assert(pplist);
    pNode pNewNode = BuyNode(d);

    if (*pplist == NULL)//无节点case
    {
        *pplist = pNewNode;
    }
    else
    {
        pNode cur = *pplist;//指向当前节点指针
        while (cur->next != NULL)
        {
            cur = cur->next;
        }
        cur->next = pNewNode;
    }
}


void PopBack(pList* pplist)
{
    assert(pplist);
    
    pNode cur = *pplist;//指向当前节点指针

    if (cur == NULL)
    {
        return;
    }
    else if (cur->next == NULL) // 只有一个节点
    {
        free(cur);
        *pplist = NULL;
        return;
    }
    while (cur->next->next != NULL)//多个节点
    {
        cur = cur->next;
    }
    free(cur->next);
    cur->next = NULL;
}

void PushFront(pList* pplist, DataType d)
{
    pNode NewNode = BuyNode(d);
    assert(pplist);
    
    if (*pplist == NULL)
        *pplist = NewNode;
    else
    {
        NewNode->next = *pplist;
        *pplist = NewNode;
    }
}

void PopFront(pList* pplist)
{
    assert(pplist);
    pNode cur = *pplist;//指向当前节点指针
    if (cur == NULL)
        return;
    
    else if (cur->next == NULL)
    {
        free(cur);
        *pplist = NULL;
    }
    else
    {
        pNode tmp = *pplist;
        *pplist = cur->next;
        free(tmp);
    }
}

void PrintList(pList plist)
{
    pNode cur = NULL;
    if (plist == NULL)
    {
        printf("null\n");
        return;
    }
    cur = plist;
    printf("list: ");
    while (cur != NULL)
    {
        printf("%d --> ", cur->data);
        cur = cur->next;
    }
    printf("NULL\n");
}

pNode Find(pList plist, DataType d)
{
    pNode cur = plist;

    while (cur)
    {
        if (cur->data == d)
        {
            return cur;
        }
        cur = cur->next;
    }
    return NULL;
}

//删除指定元素
void Remove(pList* pplist, DataType d)
{
    assert(pplist);
    pNode cur = *pplist;
    
    while (cur)
    {
        if (cur->data == d)
        {
            if (cur == *pplist)
            {
                PopFront(pplist);
            }
            else if (cur->next == NULL)
            {
                PopBack(pplist);
            }
            else
            {
                pNode tmp = cur->next;
                cur->data = tmp->data;
                cur->next = tmp->next;
                free(tmp);
                tmp = NULL;
            }
            return;
        }
        
        cur = cur->next;
    }
    return;
}

//删除全部指定元素
void RemoveAll(pList* pplist, DataType d)
{
    pNode cur = *pplist;
    pNode pon = cur->next; //防止cur丢失
    while (cur)
    {
        if (cur->data == d)
        {
            if (cur == *pplist)
            {
                PopFront(pplist);
                cur = pon; //更新cur
            }
            else if (cur->next == NULL)
            {
                PopBack(pplist);
                cur = NULL;
                break;
            }
            else 
            {
                pNode tmp = cur->next;
                
                while (tmp->data == d)
                {
                    pNode last = tmp->next;
                    cur->next = tmp->next;
                    free(tmp);
                    tmp = last;
                }
                cur->data = tmp->data;
                cur->next = tmp->next;
                free(tmp);
                tmp = NULL;
            }
        }

        cur = cur->next;
    }
    return;
}

//随机位置插入
void Insert(pList* pplist, pNode pos, DataType d)
{
    pNode cur = *pplist;
    assert(pplist);
    if (cur == NULL)
    {
        PushBack(pplist, d);
        return;
    }
    if (pos == NULL)
    {
        return;
    }
    //方法1 swap
    /*pNode NewNode = BuyNode(d);
    DataType tmp = d;
    
    tmp = NewNode->data;
    NewNode->data = pos->data;
    pos->data = tmp;
    
    NewNode->next = pos->next;
    pos->next = NewNode;*/

    //方法2 
    pNode NewNode = BuyNode(pos->data);
    pos->data = d;
    NewNode->next = pos->next;
    pos->next = NewNode;
    
}

//指定位置删除
void Erase(pList* pplist, pNode pos)
{
    pNode cur = *pplist;
    pNode prev = NULL;

    assert(pplist);

    if (cur == NULL)
        return;
    else if (pos == NULL)
        return;
    
    else if (cur == pos)
    {
        PopFront(pplist);
        return;
    }
    while (cur != pos)
    {
        prev = cur;
        cur = cur->next;
    }
    prev->next = cur->next;
    free(cur);
    cur = NULL;
}

//逆置链表
void ReverseList(pList* pplist)
{
    assert(pplist);
    pNode cur = *pplist;
    pNode newhead = *pplist;

    if (cur == NULL || cur->next == NULL)
        return;
    

    while (cur->next)
    {
        pNode tmp = cur->next;
        cur->next = tmp->next;
        tmp->next = newhead;
        newhead = tmp;
    }   
    *pplist = newhead;
}

//getsize
int getsize(pList list)
{
    pNode cur = list;
    int size = 0;
    while (cur)
    {
        size++;
        cur = cur->next;
    }
    return size;
}

//冒泡排序
void BubbleSort(pList* pplist)
{
    assert(pplist);
    pNode p = NULL;
    pNode q = NULL;

    for (p = *pplist; p != NULL; p = p->next)
    {
        for (q = p->next; q != NULL; q = q->next)
        {
            if (p->data > q->data)
            {
                DataType tmp;
                tmp = p->data;
                p->data = q->data;
                q->data = tmp;
            }
        }
    }
}

void DestroyList(pList* pplist)
{
    pNode cur = *pplist;
    assert(pplist);
    while (cur != NULL)
    {
        pNode del = cur;
        cur = cur->next;
        free(del);
    }
    *pplist = NULL;
}

//test.c

#include "list.h"

//pop/push/size
void test1()
{
    pList plist;
    InitList(&plist);

    //pushback/popback
    printf("\n test pushback\n");
    PushBack(&plist, 1);
    PushBack(&plist, 2);
    PushBack(&plist, 3);
    PrintList(plist);

int num = getsize(plist);
    printf("size: %d\n", num);

    printf("\n test popback\n");
    PopBack(&plist);
    PopBack(&plist);
    PopBack(&plist);
    PopBack(&plist);
    PrintList(plist);

    //pushfront/popfront
    printf("\n test pushfront\n");
    PushFront(&plist, 1);
    PushFront(&plist, 2);
    PushFront(&plist, 3);
    PrintList(plist);

    printf("\n test popfront\n");
    PopFront(&plist);
    PopFront(&plist);
    PopFront(&plist);
    PopFront(&plist);
    PrintList(plist);

    DestroyList(&plist);
}

//remove/removeall
void test2()
{
    pList plist;
    InitList(&plist);
    printf("\n");
    PushBack(&plist, 3);
    PushBack(&plist, 3);
    PushBack(&plist, 1);
    PushBack(&plist, 2);
    PushBack(&plist, 3);
    PushBack(&plist, 3);
    PushBack(&plist, 3);
    PushBack(&plist, 4);
    PushBack(&plist, 3);
    PushBack(&plist, 5);
    PrintList(plist);

    printf(" test remove\n");
    Remove(&plist, 3);
    Remove(&plist, 2);
    Remove(&plist, 5);
    Remove(&plist, 6);
    PrintList(plist);

    printf(" test removeall\n");
    RemoveAll(&plist, 3);
    PrintList(plist);
    RemoveAll(&plist, 3);
    PrintList(plist);

    DestroyList(&plist);
}

//find/insert/erase
void test3()
{
    pList plist;
    InitList(&plist);
    printf("\n");
    PushBack(&plist, 1);
    PushBack(&plist, 2);
    PushBack(&plist, 3);
    PushBack(&plist, 4);
    PushBack(&plist, 6);
    PushBack(&plist, 8);
    PrintList(plist);

    printf(" test insert\n");
    //中间
    pNode pos1 = Find(plist, 6);
    Insert(&plist, pos1, 5);
    //头部
    pNode pos2 = Find(plist, 1);
    Insert(&plist, pos2, 0);
    //尾部
    pNode pos3 = Find(plist, 8);
    Insert(&plist, pos3, 7);
    //节点不存在
    pNode pos4 = Find(plist, 10);
    Insert(&plist, pos4, 9);
    PrintList(plist);

    printf(" test erase\n");
    //中间
    pNode pos5 = Find(plist, 6);
    Erase(&plist, pos5);
    //头部
    pNode pos6 = Find(plist, 0);
    Erase(&plist, pos6);
    //尾部
    pNode pos7 = Find(plist, 8);
    Erase(&plist, pos7);
    //节点不存在
    pNode pos8 = Find(plist, 10);
    Erase(&plist, pos8);
    PrintList(plist);

    DestroyList(&plist);
}

//test_ReverseList
void test_ReverseList()
{
    pList plist;
    InitList(&plist);
    
    printf("\n");
    PushBack(&plist, 1);
    PushBack(&plist, 2);
    PushBack(&plist, 3);
    PushBack(&plist, 4);
    PushBack(&plist, 5);
    PushBack(&plist, 6);
    PrintList(plist);

    printf("test_ReverseList\n");
    ReverseList(&plist);
    PrintList(plist);

    DestroyList(&plist);
}

//test_BubbleSort
void test_BubbleSort()
{
    pList plist;
    InitList(&plist);
    
    printf("\n");
    PushBack(&plist, 3);
    PushBack(&plist, 6);
    PushBack(&plist, 5);
    PushBack(&plist, 8);
    PushBack(&plist, 1);
    PushBack(&plist, 4);
    PushBack(&plist, 7);
    PushBack(&plist, 2);
    PrintList(plist);
    
    printf("test_BubbleSort\n");
    BubbleSort(&plist);
    PrintList(plist);

    DestroyList(&plist);
}

int main()
{
    test1();
    test2();
    test3();
    test_ReverseList();
    test_BubbleSort();

    system("pause");
    return 0;
}

链表及链表面试题(一)入门
链表面试题(二)基础
链表面试题(三)进阶

上一篇下一篇

猜你喜欢

热点阅读