非循環單鏈表的創建、遍歷、排序等

上周看了3次數據結構的視頻,現在看起來,盡然能聽的懂??,貌似記得大學的時候 數據結構 這門課程,60分壓線及格過的吶??。。。

下面來看看這部分的代碼吧,扔圖哈,比著自己敲一下,肯定能加深印象,你比伸手黨好多了。。。關于這部分代碼估計沒人講或者沒有視頻是看不懂的,那就辛苦下,多看幾遍,熟讀唐詩3百首,不會作詩也會吟。。。

記得要用 Xcode 中的命令行工具建立工程哈~

鏈表

呃~~貌似不能全部截圖
好吧,下面放代碼:

//
//  main.m
//  鏈表創建和遍歷
//
//  Created by 小伴 on 16/7/6.
//  Copyright ? 2016年 huangqimeng. All rights reserved.
//

#import <Foundation/Foundation.h>

#include <stdio.h>
#include <malloc/malloc.h>
#include <stdlib.h>

/**
 *  節點的數據類型:包括數據域和指針域
 */
typedef struct Node {
    int data;   //數據域
    struct Node *pNext; //指針域
} NODE, *PNODE;  //NODE 等價于 struct Node ; PNODE 等價于 struct Node *

/**
 *  函數聲明
 */
/** 創建 */
PNODE create_list(void);
/** 遍歷 */
void traverse_list(PNODE pHead);
/** 判空 */
bool is_empty(PNODE pHead);
/** 長度 */
int length_list(PNODE);
/** 插入 */
bool insert_list(PNODE, int, int);
/** 刪除 */
bool delete_list(PNODE, int, int *);
/** 排序 */
void sort_list(PNODE);


int main(int argc, const char * argv[]) {
    @autoreleasepool {

        PNODE pHead = NULL; //等價于struct Node * pHead = NULL;

        pHead = create_list(); //創建一個非循環單鏈表,并將該鏈表的頭結點的地址賦給 pHead
        traverse_list(pHead); //遍歷

        /*
        insert_list(pHead, 3, 45);
        traverse_list(pHead);
         */

        int val;
        if (delete_list(pHead, 3, &val)) {
            printf("刪除成功,刪除的元素是:%d\n", val);
        } else {
            printf("刪除失敗,刪除的元素不存在!\n");
        }
        traverse_list(pHead);


        int len = length_list(pHead);
        printf("長度len = %d\n", len);

        sort_list(pHead);
        traverse_list(pHead);

        /*
        if (is_empty(pHead)) {
            printf("鏈表為空\n");
        } else {
            printf("鏈表不空\n");
        }*/

    }
    return 0;
}

/**
 *  創建非循環單鏈表
 */
PNODE create_list() {
    int len; //存放有效節點的個數
    int i;
    int val; //臨時存放用戶輸入的節點的值

    //分配一個不存放有效數據的頭節點
    PNODE pHead = (PNODE)malloc(sizeof(NODE));
    if (pHead == NULL) {
        printf("分配失敗,程序終止\n");
        exit(-1); //程序終止
    }

    PNODE pTail = pHead;
    pTail->pNext = NULL;

    printf("輸入需要生成的鏈表的節點個數:len = ");
    scanf("%d", &len);

    for (i = 0; i < len; i++) {
        printf("輸入第 %d 個節點的值:", i + 1);
        scanf("%d", &val);

        PNODE pNew = (PNODE)malloc(sizeof(NODE));
        if (pNew == NULL) {
            printf("分配失敗,程序終止\n");
            exit(-1);
        }
        pNew->data = val;
        pTail->pNext = pNew;
        pNew->pNext = NULL;
        pTail = pNew;
    }

    return pHead;
}

/**
 *  遍歷非循環單鏈表
 */
void traverse_list(PNODE pHead) {
    PNODE p = pHead->pNext;
    while (p != NULL) {
        printf("%d ", p->data);
        p = p->pNext;
    }
    printf("\n");
}

/**
 *  判空
 */
bool is_empty(PNODE pHead) {
    if (pHead->pNext == NULL) {
        return true;
    } else {
        return false;
    }
}

/**
 *  長度
 */
int length_list(PNODE pHead) {
    PNODE p = pHead->pNext;
    int len = 0;

    while (p!= NULL) {
        len++;
        p=p->pNext;
    }

    return len;
}

/**
 *  排序
 */
void sort_list(PNODE pHead) {
    int i, j, t;
    int len = length_list(pHead);
    PNODE p, q;

    for (i = 0, p = pHead->pNext; i < len-1; i++, p = p->pNext) {
        for (j = i+1, q = p->pNext; j < len; j++, q = q->pNext) {
            if (p->data > q->data) {//類似數組中的a[i] > a[j]
                t = p->data; //t = a[i];
                p->data = q->data; //a[i] = a[j];
                q->data = t; //a[j] = t;
            }
        }
    }
}

/**
 *  在pHead所指向鏈表的第pos個節點的前面插入一個新的節點,該節點的值是val,并且pos的值是從1開始的
 */
///經典的算法
bool insert_list(PNODE pHead, int pos, int val) {
    int i = 0;
    PNODE p = pHead;

    while (p != NULL && i < pos - 1) {
        p = p->pNext;
        ++i;
    }

    //不需要判斷鏈表空、滿、算長度
    if (i > pos - 1 || p == NULL) {
        return false;
    } else {
        PNODE pNew = (PNODE)malloc(sizeof(NODE));
        if (pNew == NULL) {
            printf("動態內存分配失敗!\n");
            exit(-1);
        } else {
            pNew->data = val;
            PNODE temp = p->pNext;
            p->pNext = pNew;
            pNew->pNext = temp;

            return true;
        }
    }
}

bool delete_list(PNODE pHead, int pos, int *pVal) {
    int i = 0;
    PNODE p = pHead;

    while (p->pNext != NULL && i < pos - 1) {
        p = p->pNext;
        ++i;
    }

    if (i > pos - 1 || p->pNext == NULL) {
        return false;
    } else {
        PNODE pNew = (PNODE)malloc(sizeof(NODE));
        if (pNew == NULL) {
            printf("動態內存分配失敗!\n");
            exit(-1);
        } else {
            PNODE temp = p->pNext;
            *pVal = temp->data;

            //刪除p節點后面的節點
            p->pNext = p->pNext->pNext;
            free(temp);
            temp = NULL;

            return true;
        }
    }
}

自己研究去吧。。。祝你早日看的懂~
鏈表的插入和刪除已經更新了,最強鏈表的算法拿走不謝,最后插入和刪除的算法特別經典,好好看看爭取弄懂他。

碎覺??

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,115評論 25 708
  • 今天,賴聲川的話劇《暗戀桃花源》再度來滬演出。作為看過兩次現場,以及電影版的資深粉,熱烈地翻出陳年舊篇來應個景。2...
    一玫艾姐閱讀 961評論 0 50
  • 文 ▏ 黃銘峰 記得有一天我和我的學生一起吃午飯的時候在交流學習的心得體會。 我建議我們學生,有時間要多閱讀中外的...
    通識智庫閱讀 379評論 0 6
  • 給定一個整數序列,找到最長上升子序列(LIS),返回LIS的長度。 說明 最長上升子序列的定義: 最長上升子序列問...
    Arnold134777閱讀 1,014評論 0 0