C言語の回顧--行列の入隊と出隊


---------------------------------------------------
前言:
先日海康威視の筆記試験をしましたが、ちょうど大きな問題がC言語でプログラミングして行列の入隊と出隊の機能を実現しました.そこで試験が終わったら自分でその時書いたコードをデバッグします.誤りが多いです.何時間の努力を経てデバッグが成功しました.
---------------------------------------------------
列に並んでご飯を買うのと同じで、先に来た人が先にご飯を買って、買ってから出発します.後に来る人は列に並ぶしかないです.だから、今回のプログラミングはチェーン形式でテーマの需要を実現します.
行列の頭と尾を表していますか?ここでは、2つのポインタを導入して、それぞれ最初のノードの先頭ポインタを指して、尾ノードの尾ポインタを指します.どうやって移動しますか?考えてもいいです.ご飯を買う時は順番に並んでいますが、ご飯を買う窓口は決まっています.窓口に行くしかないです.おばさんは何を食べますか?だから先进的な先出のこの道理を言います.更に簡単な話、あなたのpTail NodeはずっとpHeadNodeに迷惑をかけています.pHeadNodeはまたお父さんのようにお尻を塗って解決します.
コードフローは以下の通りです.
構造体の定義は以下の通りです.
typedef struct _QUEUE_NODE_         //           
{
    struct _QUEUE_NODE_ *pNextNode;
    int                       data;
}QUEUE_NODE,*PQUEUE_NODE;

  :
1.            void *  ,        int      ;
2.           _QUEUE_NODE_,               QUEUE_NODE,    QUEUE_NODE = struct _QUEUE_NODE_ , *PQUEUE_NODE ?
  ,*PQUEUE_NODE = (struct _QUEUE_NODE_ *),       QUEUE_NODE,PQUEUE_NODE  ;
3.       1     ,1        (         );
typedef struct QUEUE        //      
{
    QUEUE_NODE *pHeadNode;
    QUEUE_NODE *pTailNode;
}QUEUE_HANDLE,*PQUEUE_HANDLE;

  :
1.              QUEUE,       ,        QUEUE_HANDLE PQUEUE_HANDLE;
2.         ,QUEUE_HANDLE = struct QUEUE ;PQUEUE_HANDLE = (struct QUEUE *);
3.      2   ,      ,pHeadNode              ,pTailNode               ;
入隊の関数: 
QUEUE_HANDLE *insert(QUEUE_HANDLE *HQ,int Data)    //  
{
    PQUEUE_NODE s;

    if(HQ == NULL)                                   //    
    {
        printf("HQ value is NULL.
"); return NULL; } s = (QUEUE_NODE *)malloc(sizeof(QUEUE_NODE)); // s->data = Data; s->pNextNode = NULL; if(HQ->pTailNode == NULL && HQ->pHeadNode == NULL) // : { HQ->pHeadNode = s; HQ->pTailNode = s; } else // { HQ->pTailNode->pNextNode = s; HQ->pTailNode = s; } return HQ; }
出力関数:
QUEUE_HANDLE *out(QUEUE_HANDLE *HQ)
{
    QUEUE_NODE *p;
    p = HQ->pHeadNode;
    
    if(p == NULL)
    {
        printf("yichu
"); return NULL; } else { printf("queue data:%d
",p->data); printf("queue adress:%p
",p); if(HQ->pHeadNode == HQ->pTailNode) // : { HQ->pHeadNode = NULL; HQ->pTailNode = NULL; free(p); p = NULL; // p Free ; } else // { HQ->pHeadNode = HQ->pHeadNode->pNextNode; free(p); } return HQ; } }
完全なコード:エルゴード関数と上記の関数を使用した呼び出しを含みます.
/*********************************************************************************
 *      Copyright:  (C) 2018 guozhihao
 *                  All rights reserved.
 *
 *       Filename:  homework.c
 *    Description:  This file 
 *                 
 *        Version:  1.1.0(10/27/2019)
 *         Author:  Guozhihao <[email protected]>
 *      ChangeLog:  2, Release initial version on "10/27/2019 08:35:03 PM"
 *                 
 ********************************************************************************/
#include 
#include 
typedef struct _QUEUE_NODE_
{
    struct _QUEUE_NODE_ *pNextNode;
    int                       data;
}QUEUE_NODE,*PQUEUE_NODE;

typedef struct QUEUE
{
    QUEUE_NODE *pHeadNode;
    QUEUE_NODE *pTailNode;
}QUEUE_HANDLE,*PQUEUE_HANDLE;

QUEUE_HANDLE *insert(QUEUE_HANDLE *HQ,int Data)
{
    
    if(HQ == NULL)
    {
        printf("HQ value is NULL.
"); return NULL; } PQUEUE_NODE s; s = (QUEUE_NODE *)malloc(sizeof(QUEUE_NODE)); s->data = Data; s->pNextNode = NULL; if(HQ->pTailNode == NULL && HQ->pHeadNode == NULL) { HQ->pHeadNode = s; HQ->pTailNode = s; } else { HQ->pTailNode->pNextNode = s; HQ->pTailNode = s; } return HQ; } QUEUE_HANDLE *out(QUEUE_HANDLE *HQ) { QUEUE_NODE *p; p = HQ->pHeadNode; if(p == NULL) { printf("yichu
"); return NULL; } else { printf("queue data:%d
",p->data); printf("queue adress:%p
",p); if(HQ->pHeadNode == HQ->pTailNode) { HQ->pHeadNode = NULL; HQ->pTailNode = NULL; free(p); p = NULL; } else { HQ->pHeadNode = HQ->pHeadNode->pNextNode; free(p); p = NULL; } return HQ; } } void travel(QUEUE_HANDLE *HQ) { QUEUE_NODE *p; p = HQ->pHeadNode; while(p != NULL) { printf("queue data:%d
",p->data); printf("queue adress:%p
",p); p = p->pNextNode; } } int main (int argc, char **argv) { QUEUE_HANDLE *HQ ; int i; HQ = (QUEUE_HANDLE *)malloc(sizeof(QUEUE_HANDLE)); HQ->pTailNode = NULL; HQ->pHeadNode = NULL; printf("now start to add new node:
"); for(i = 0;i<10;i++) { HQ = insert(HQ,i); if(!HQ) { printf("HQ insert failed.
"); goto END_EXIT; } } travel(HQ); printf("now start to free node:
"); #if 1 for(i = 0;i<5;i++) { HQ = out(HQ); if(!HQ) { printf("HQ is NULL.
"); goto END_EXIT; } } printf("The remaining node:
"); #endif travel(HQ); END_EXIT: if(HQ) { free(HQ); } return 0; } /* ----- End of main() ----- */
makefileファイルを添付します.
# /bin/bash

PWD := $(shell pwd)

filename := duilie

testfile :=${PWD}/${filename}

tools:=gcc

all: GCC

GCC:
        ${tools} ${testfile}.c -o ${filename} -Wall
        @echo " gcc ${testfile} successfully!";
        ./${filename}

debug:
        gcc -g ${testfile}.c -o ${filename}
        gdb ${testfile}

cleanup:
        @rm ${filename}
プログラム運転結果:
[guozhihao@bogon shujujiegou]$ make
gcc /home/guozhihao/Master/guozhihao/C6/shujujiegou/duilie.c -o duilie -Wall
 gcc /home/guozhihao/Master/guozhihao/C6/shujujiegou/duilie successfully!
./duilie
now start to add new node:
queue data:0
queue adress:0x14bd030
queue data:1
queue adress:0x14bd050
queue data:2
queue adress:0x14bd070
queue data:3
queue adress:0x14bd090
queue data:4
queue adress:0x14bd0b0
queue data:5
queue adress:0x14bd0d0
queue data:6
queue adress:0x14bd0f0
queue data:7
queue adress:0x14bd110
queue data:8
queue adress:0x14bd130
queue data:9
queue adress:0x14bd150
now start to free node:
queue data:0
queue adress:0x14bd030
queue data:1
queue adress:0x14bd050
queue data:2
queue adress:0x14bd070
queue data:3
queue adress:0x14bd090
queue data:4
queue adress:0x14bd0b0
The remaining node:
queue data:5
queue adress:0x14bd0d0
queue data:6
queue adress:0x14bd0f0
queue data:7
queue adress:0x14bd110
queue data:8
queue adress:0x14bd130
queue data:9
queue adress:0x14bd150
 
思考:
pHeadNodeポインタがpTail Nodeの手配を処理した後に出会います.両方がNULLに向けています.これは簡単な処理方法です.もう一つは自分に点数を付ける方法があります.つまり循環列の思想で解決します.