1. 程式人生 > >C 無頭結點單鏈表若干操作

C 無頭結點單鏈表若干操作

顧名思義就是從一開就是有用的結點

文章目錄

定義結構體

typedef struct Node {
    int element;
    struct Node *next;
}LNode, * LinkNode;

建立

這裡是手輸入,輸入為0的時候就退出來

//傳入一個頭指標的地址
void create(LinkNode *head){
	//這裡就用p1, p2迴圈插入即可
    LinkNode p1,
p2; p1 = p2 = (LinkNode)malloc(sizeof(LNode)); (*head) = NULL; //先建立一個結點 int a, n = 0; scanf("%d", &a); p1->element = a; //當結構體的值不為零的時候就迴圈往復地走 while (p1->element != 0) { n++; if(n == 1){ //要是第一個結點特別標記 *head = p1; }else{
//要不是第一個節點的話,上次迴圈中新建立的p1就成為連結串列最後一個節點 p2->next = p1; } //將p2指向最後一個節點 p2 = p1; //新建立一個節點,初始化,這個還沒判斷a是不是等於零先放著 p1 = (LinkNode)malloc(sizeof(LNode)); scanf("%d", &a); p1->element = a; } //迴圈結束,就不再 p2->next = NULL
; }

輸出連結串列的值

void putout(LinkNode p){
    while (p) {
        printf("%d", p->element);
        p = p->next;
    }
    printf("\n");
}

在第i個位置前插入

要是空的連結串列將其視為第一個,要是i比整個連結串列都要大那就加在最後一個

//在第i個位置前插入元素e
void insertElemnt(LinkNode * p, int i, int e) {
    int n = i;
   	//先建立兩個節點,p1指向最新的,p2指向p1的前一個
    LinkNode p1 = *p, p2 = NULL;
    //建立一個待插入的節點
    LinkNode insertE = (LinkNode)malloc(sizeof(LNode));
    insertE->element = e;
    insertE->next = NULL;
    //如果連結串列整體為空,那插入的就是第一個了
    if(p1 == NULL){
        *p = insertE;
    }
    /*如果在最前面插入的話,那就頭結點就是新插入的這個,原來的頭結點
    退居第二個*/
    else if (n == 1)
    {
        *p = insertE;
        insertE->next = p1;
    }
    //一般的情況
    else{
    	//前提是插入節點的前面的那個節點不能為空
        while (p1) {
        	//要是n=1,那就找對了位置,出來就可以了,那麼p1就是第n個
            if(n == 1) break;
            //p2總也是p1的前面那個節點
            p2 = p1;
            p1 = p1->next;
            n--;
        }
        //進行插入,在p2和p1之間將其插進去
        p2->next = insertE;
        //p1有可能為空,為空就讓其等於NULL
        insertE->next = p1 ? p1 : NULL;
    }
}

刪除第i個節點

要是空的連結串列返回,要是i比整個連結串列都要大那就刪除最後一個

void deleteElement(LinkNode *p, int i){
	if(!*p) return;
	//還是原來的樣子找p1就是該刪的,p2是p1的前一個
    LinkNode p1 = *p, p2 = NULL;
    int n = i;
    //要是在第一個的話,頭指標後移一位
    if(n == 1){
        *p = p1->next;
    }else
    {	
    	//一直迴圈直到最後一個
        while (p1->next) {
        	//到位置了
            if(n == 1) break;
            //p2就是p1的前面那個
            p2 = p1;
            p1 = p1->next;
            n--;
        }
        /*要是p2後面還有內容,p2就不是最後一個,說明p1就是第i個,i合法
        如果i不合法,p1就是最後一個跳出來了,那就刪除最後一個就好了,
        其實這裡可以判斷n的值是不是等於1,就可以知道是i不合法還是到
        位置了*/
        if(p2->next) {
            p2->next = p1->next;
        }
        //如果只有一個的話,那就都刪了;
        if(*p == p1){
            *p = NULL;
        }
        //釋放p1;
        free(p1);
    }
}

頭插法

//頭插法
void headInsert(LinkNode *p, int e){
	//每次也都是在第一個節點插入,我只需記錄第一個節點,新的節點指向他就好了
    LinkNode p1 = *p;
    LinkNode insertE = (LinkNode)malloc(sizeof(LNode));
    insertE->element = e;
    
    *p = insertE;
    insertE->next = p1;
}

尾插法

//尾插法
void tailInsert(LinkNode *p, int e){
    //我新建一個節點
    LinkNode insertE = (LinkNode)malloc(sizeof(LNode));
    insertE->element = e;
    insertE->next = NULL;
    //遍歷到最後一個節點
    LinkNode p1 = *p;
    while (p1->next) {
        p1 = p1->next;
    }
    //p1就是最後一個節點,就此往後只一個就OK了
    p1->next = insertE;
}

完整程式程式碼

//
//  main.c
//
//  Created by 赫凱 on 2018/10/21.
//  Copyright © 2018年 赫凱. All rights reserved.
//

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

typedef struct Node {
    int element;
    struct Node *next;
}LNode, * LinkNode;

//建立結構體
void create(LinkNode *head){
    LinkNode p1, p2;
    p1 = p2  = (LinkNode)malloc(sizeof(LNode));
    (*head) = NULL;
    
    int a, n = 0;
    scanf("%d", &a);
    p1->element = a;
    
    while (a != 0) {
        n++;
        if(n == 1){
            *head = p1;
        }else{
            p2->next = p1;
        }
        p2 = p1;
        
        p1 = (LinkNode)malloc(sizeof(LNode));
        scanf("%d", &a);
        p1->element = a;
    }
    p2->next = NULL;
}

//輸出單鏈表
void putout(LinkNode p){
    while (p) {
        printf("%d ", p->element);
        p = p->next;
    }
    printf("\n");
}

//單鏈表訪問第i個元素
int find(LinkNode p, int i){
    LinkNode p1 = p;
    int j = 1;
    while (p1) {
        if(j == i){
            return p1->element;
        }
        j++;
        p1 = p1->next;
    }
    return 0;
}
//在第i個位置前插入元素e
void insertElemnt(LinkNode * p, int i, int e) {
    int n = i;
    
    LinkNode p1 = *p, p2 = NULL;
    
    LinkNode insertE = (LinkNode)malloc(sizeof(LNode));
    insertE->element = e;
    insertE->next = NULL;
    
    if(p1 == NULL){
        *p = insertE;
    }else if (n == 1)
    {
        *p = insertE;
        insertE->next = p1;
    }
    else{
        while (p1) {
            if(n == 1) break;
            p2 = p1;
            p1 = p1->next;
            n--;
        }
        p2->next = insertE;
        insertE->next = p1?p1:NULL;
    }
}

//刪除第i個元素
void deleteElement(LinkNode *p, int i){
    LinkNode p1 = *p, p2 = NULL;
    int n = i;
    if(n == 1){
        *p = p1->next;
    }else
    {
        p2 = p1;
        while (p1->next) {
            if(n == 1) break;
            p2 = p1;
            p1 = p1->next;
            n--;
        }
        
        if(p2->next) {
            p2->next = p1->next;
        }
        if(*p == p1){
            *p = NULL;
        }
        free(p1);
    }
}
//頭插法
void headInsert(LinkNode *p, int e){
    LinkNode p1 = *p;
    LinkNode insertE = (LinkNode)malloc(sizeof(LNode));
    insertE->element = e;
    
    *p = insertE;
    insertE->next = p1;
}
//尾插法
void tailInsert(LinkNode *p, int e){
    
    LinkNode insertE = (LinkNode)malloc(sizeof(LNode));
    insertE->element = e;
    insertE->next = NULL;
    
    LinkNode p1 = *p;
    while (p1->next) {
        p1 = p1->next;
    }
    p1->next = insertE;
}
int main(int argc, const char * argv[]) {
    // insert code here...
    printf("Hello, World!\n");
    
    LinkNode head;
    create(&head);
    putout(head);
    
    printf("%d",find(head, 2));
    
    printf("\n");
    
    insertElemnt(&head, 3, 4);

    putout(head);
    deleteElement(&head, 3);
    putout(head);
    int i;
    for (i = 1; i < 8; i++) {
        headInsert(&head, i);
        tailInsert(&head, i);
    }
    putout(head);
    return 0;
}