数据结构(1)-链表

数据结构在编程中或多或少都会用到,也是程序员面试最喜欢问的知识块之一,可以说非常基础了。本篇文章主要介绍链表,但不从理论部分介绍,直接给出链表的实现代码。当然,本人还是建议先看一遍链表理论部分的知识再来看本文的程序,这样掌握的更快更牢。相关的理论知识可以查看相关书籍或直接百度。下面直接上代码。

/*-----------------------------程序描述--------------------------------------------
* 本程序展示链表的创建、输出、删除、插入和查找等操作。主函数中分别调用
* (1) 建立链表的函数Creat(),
* (2) 输出链表的函数Print(),
* (3) 查找结点的函数Find(),
* (4) 插入结点的函数Insert(),
* (5) 逆转结点的函数Reversed(),
* (6) 删除链表结点的函数Delete(),
* (7) 清屏
* (8) 退出
* (9) 每K个结点逆转的函数KReversed(),
* 一共9个函数。

* Author:EthanYYYY
* Date:  2017.12.20
----------------------------------------------------------------------------------*/

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

typedef struct node{
    int _val;
    struct node* next;
}Node;

int _iNodeCout;

Node* Creat();
Node* Delete(Node*,int);
void Find(Node* ,int);
Node* Insert(Node*,Node*);
void Print(Node*);
Node* Reversed(Node*);
Node* KReversed(Node*,int);

int main(int argc, char *argv[])
{
    volatile int _iChoice;
    int _iNode;
    Node* pHead=NULL;
    Node* insertNode=NULL;
    int k;
    do
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
        printf("\n\t ------------------------------------------------------");
        printf("\n\t|         [1] creat             [2] print              |");
        printf("\n\t|         [3] search            [4] insert             |");
        printf("\n\t|         [5] reversed          [6] delete             |");
        printf("\n\t|         [7] clear             [8] exit               |");
        printf("\n\t|         [9] K-reversed        [10]                   |");
        printf("\n\t ------------------------------------------------------\n");
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),7|0);

        printf("you choice: ");
        scanf("%d",&_iChoice);

        switch (_iChoice)
        {
        case 1:
            pHead=Creat();
            break;
        case 2:
            Print(pHead);
            break;
        case 3:
        {
            printf("input search node:");
            scanf("%d",&_iNode);
            Find(pHead,_iNode);
        }
            break;
        case 4:
        {
            printf("input insert node:");
            insertNode=(Node*)malloc(sizeof(Node));
            scanf("%d",&insertNode->_val);
            insertNode->next=NULL;
            pHead=Insert(pHead,insertNode);
        }
            break;
        case 5:
            pHead=Reversed(pHead);
            break;
        case 6:
        {
            printf("input delete node:");
            scanf("%d",&_iNode);
            pHead=Delete(pHead,_iNode);
        }
            break;
        case 7:
            system("CLS");
            break;
        case 8:
            _iChoice=-1;
            break;
        case 9:
        {
                printf("input K = ");
                scanf("%d",&k);
                pHead=KReversed(pHead,k);
        }
            break;
        default:
            puts("invaild,choose again!");
            break;
        }
    } while (_iChoice!=-1);

    system("pause");
    return 0;
}

Node* Creat()
{
    Node* pHead=NULL,* pCur,* pTail;
    _iNodeCout=0;
    puts("input node, end whit -1:");
    pCur=pTail=(Node*)malloc(sizeof(Node));
    scanf("%d",&pCur->_val);
    pCur->next=NULL;
    while (pCur->_val!=-1)
    {
        _iNodeCout++;
        if(1==_iNodeCout) pHead=pCur;
        else pTail->next=pCur;
        pTail=pCur;
        pCur=(Node*)malloc(sizeof(Node));
        scanf("%d",&pCur->_val);
        pCur->next=NULL;
    }
    free(pCur);
    pCur=NULL;
    pTail->next=NULL;
    return pHead;
}

Node* Delete(Node* pHead,int _iNode)
{
    Node* pCur=pHead;
    Node* pPre=NULL;
    if(NULL==pHead){
        printf("\n\tThis is NULL!\n");
        return NULL;
    }
    while (NULL!=pCur&&pCur->_val!=_iNode)
    {
        pPre=pCur;
        pCur=pCur->next;
    }

    if (NULL==pCur)
    {
        printf("\t%d has not been Found!\n",_iNode);
        return pHead;
    }

    if (NULL==pPre)
    {
        pPre=pCur;
        pCur=pCur->next;
        pHead=pCur;
        free(pPre);
        return pHead;
    }
    pPre->next=pCur->next;
    free(pCur);
    _iNodeCout--;
    return pHead;
}

void Find(Node* pHead,int _iNode)
{
    Node* pCur=pHead;
    if(NULL==pHead){printf("\n\tThis is NULL!\n");return;}
    while ( NULL!=pCur && pCur->_val!=_iNode )
        pCur=pCur->next;

    if (NULL==pCur)printf("%d has not been found!\n ",_iNode);
    else printf("%d has been found!\n ",_iNode);
}

Node* Insert(Node* pHead,Node* insertNode)
{
    Node* pCur=pHead,* pPre=NULL;

    if (NULL==pCur)
    {
        pHead=insertNode;
        insertNode->next=NULL;
    }
    else
    {
        while (pCur!=NULL&&pCur->_val<insertNode->_val)
        {
            pPre=pCur;
            pCur=pCur->next;
        }

        if (pCur->_val>insertNode->_val)
        {
            if (NULL==pPre) //在表头插入
                pHead=insertNode;
            else
                pPre->next=insertNode;
            insertNode->next=pCur;
        }
        else   // 表尾插入
        {
            pCur->next=insertNode;
            insertNode->next=NULL;
        }
    }
    _iNodeCout++;
    return pHead;
}

void Print(Node* pHead)
{
    Node* pCur=pHead;
    if(NULL==pHead){printf("\n\tThis is NULL!\n");return;}
    puts("output is: ");
    do
    {
        printf("%d->",pCur->_val);
        pCur=pCur->next;
    } while (NULL!=pCur);
    printf("NULL");
}

// 逆转链表 -- 迭代实现
Node* Reversed(Node* pHead)
{
    Node* pCur=pHead;
    Node* pPre=NULL;
    if(NULL==pHead){printf("\n\tThis is NULL!\n");return pHead;}
    while (NULL!=pCur)
    {
        Node* pNext=pCur->next;
        //if(NULL==pNewHead) pNewHead=pPre;
        pCur->next=pPre;
        pPre=pCur;
        pCur=pNext;
    }
    return pPre;
}

// 逆转链表 -- 递归实现
Node* ReversedNode_1(Node* pHead)
{
    Node* p,* pNewHead;

    if (pHead == NULL || pHead -> next == NULL)
    {
        return pHead;
    }
    p = pHead -> next;
    pNewHead =  ReversedNode_1(p);
    p -> next = pHead;
    pHead ->next = NULL;
    return pNewHead;
}


//---------------- K 逆转链表 ----------------------
Node* KInvert(Node* pHead)
{
    Node* pCurr;
    Node* pNewHead=NULL;
    if (NULL==pHead)
        return pHead;

    while (pHead)
    {
        pCurr=pHead;
        pHead=pHead->next;
        pCurr->next=pNewHead;
        pNewHead=pCurr;
    }
    return pNewHead;
}

Node* GetLastNode(Node* pHead)
{
    while (NULL!=pHead->next)
        pHead=pHead->next;
    return pHead;
}

Node* KReversed(Node* pHead,int iK)
{
    int iPos; //
    Node* pCurr=pHead;
    Node* pNewHead;
    Node* pNextNode;
    Node* pLastNode=NULL;
    if(iK<=1) return pHead;
    pHead=NULL;

    while (pCurr)
    {
        iPos=0;
        pNewHead=pCurr;
        while (pCurr&&iPos<iK-1)
        {
            pCurr=pCurr->next;
            iPos++;
        }

        if (pCurr)
        {
            pNextNode=pCurr->next;
            pCurr->next=NULL;

            pNewHead=KInvert(pNewHead);
            if (NULL==pHead)
                pHead=pNewHead;
            else
                pLastNode->next=pNewHead;

            // 获取上面那段链表的尾节点
            pCurr=GetLastNode(pNewHead);
            pCurr->next=pNextNode;
            pLastNode=pCurr;
            pCurr=pNextNode;
        }
    }
    return pHead;
}


在一般的面试中,如果涉及到链表,很多面试官会让你写出如何将单向链表中的某个节点删除的代码或者伪码。所以如果你最近要参加面试,可着重看删除这部分,结合理论,会掌握的更好。

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