非迴圈單連結串列的建立、遍歷、排序等

weixin_34185560發表於2016-07-12

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

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

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

1291197-b94e7f89fc05fb44.png
連結串列

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

//
//  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;
        }
    }
}

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

碎覺?

相關文章