单链表基本操作(2)

单链表基本操作(2)

  • 公共结构体
  • 模拟测试链表
  • 展示链表数据
  • 定位

    1. 按号定位
    2. 按值定位
  • 求链表长度
  • 插入
  • 删除
  • 合并

1.公共结构体

创建结构类型,在CS.c文件中


typedef struct node{
    int data;
    struct node *next;
}LINKLIST;

2.模拟测试链表

在Link.h写出方法声明

/* 模拟链表数据 */
LINKLIST *testLinkList();

在Link.c中实现此方法

#include "Link.h"

LINKLIST *testLinkList(){
    LINKLIST  *Q,*L;
    Q=(LINKLIST *)malloc(sizeof(LINKLIST));
    L=Q;
    Q->data=-1;
    Q->next=NULL;

    int x=0;
    LINKLIST *temp;
    while(x!=10){
        x++;
        temp=(LINKLIST *)malloc(sizeof(LINKLIST));
        temp->data=x;
        temp->next=NULL;
        Q->next=temp;
        Q=temp;
    };
    return L;
}

使用的是尾插入方式插入数据

在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断

#include <stdio.h>
#include "Link.h"
int main(int argc, const char * argv[]) {
    LINKLIST *SQ=testLinkList();
}

3.展示链表数据

link.h 声明方法

/* 打印链表中的节点数据 */

void showLinkList(LINKLIST *Q);

link.c 实现方法


void showLinkList(LINKLIST *Q){
    LINKLIST *p;
    p=Q;
    printf("list=[");
    while (p!=NULL) {
        if(p->data==-1){
            printf("%d",p->data);
        }else{
            printf(",%d",p->data);
        }
        p=p->next;
    }
    printf("]\n");
}

在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断

#include <stdio.h>
#include "Link.h"
int main(int argc, const char * argv[]) {

    LINKLIST *SQ=testLinkList();
    showLinkList(SQ);
}

打印结果:

list=[-1,1,2,3,4,5,6,7,8,9,10]

4.定位

4.1按号定位

link.h 声明

/* 查找链表中指定位置的元素是否存在--按号定位 */
LINKLIST *locbn(LINKLIST *Q,int i);

link.c 实现

LINKLIST *locbn(LINKLIST *Q,int i){
    LINKLIST *p;

    int j=0;
    //1.判断查找的位置是否小于等于0,因为不存在此节点,则直接返回NULL
    if(i<=0){
        return NULL;
    }
    p=Q;
    //2.判断当前计数j是否等于i,如果不等于,则表示还没有找到要查找的位置,并且当前p不能为NULL
    while (j!=i&& p!=NULL) {
        //3.判断条件不成立,则继续查找下一个节点
        p= p->next;
        //4.计数器自增+1
        j++;
    }
    return  p;
}

在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断

#include <stdio.h>
#include "Link.h"
int main(int argc, const char * argv[]) {

     printf("定位->按号定位\n");
     //按号定位
     LINKLIST *SQ=testLinkList();
    int index=8;
    LINKLIST *p=locbn(SQ,index);
    if(p!=NULL){
        printf("SQ in %d node of data =%d \n",index,p->data);
    }else{
        printf("SQ 不存在此 %d 位置的节点 \n",index);
    }

}

打印结果:

定位->按号定位
SQ in 8 node of data =8 

4.2按值定位

link.h 声明

/* 查找链表中指定位置的元素是否存在--按值定位 */
LINKLIST *locbv(LINKLIST *Q,int x);

link.c 实现

LINKLIST *locbv(LINKLIST *Q,int x){
    LINKLIST *p;
    p=Q;
    //1.当前节点不能为NULL,并且查找的数据域data不等于要查找的数值x,则表示还没找到要查找的数值
    while (p!=NULL && p->data!=x){
        //2.条件不成立,则继续往下一个节点查找
        p=p->next;
    }

    return p;
}

在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断

#include <stdio.h>
#include "Link.h"
int main(int argc, const char * argv[]) {

     //按值定位
      printf("定位->按值定位\n");
      LINKLIST *SQ=testLinkList();
     int value=80;
     LINKLIST *pv=locbn(SQ,value);
    if(pv!=NULL){
        printf(" %d in linkst ,值为 %d\n",value,pv->data);
    }else{
        printf("SQ 不存在此 %d 值的节点 \n",value);
    }

}

打印结果:

定位->按值定位
SQ 不存在此 80 值的节点

5.求链表长度

link.h 声明方法

/* 求链表长度 */
int  lenll(LINKLIST *Q);

link.c 实现方法

int  lenll(LINKLIST *Q){

    int  len=0;
    LINKLIST *p;
    p=Q;
    //1.第一判断链表不为NULL,并且下一个指针域也不为NULL
    //3.len变量自增+1
    for(;p!=NULL && p->next!=NULL;len++){
        //2.将指针域赋给当前节点变量,即:往下查找一个节点
        p=p->next;
    }
    return len;
}

在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断

#include <stdio.h>
#include "Link.h"
int main(int argc, const char * argv[]) {

    LINKLIST *SQ=testLinkList();
    //求链表长度
    printf("求链表长度\n");
    int  len=lenll(SQ);
    printf("链表长度=%d \n",len);

}

打印结果:

求链表长度
链表长度=10 

6.插入

link.h 声明方法

/* 向指定位置插入结点 */
LINKLIST * insterByPosition(LINKLIST *Q,int position);

link.c 实现方法


LINKLIST * insterByPosition(LINKLIST *Q,int position){
    LINKLIST  *q;
    //为了不改变原来的链表
    q=Q;
    //1.先找到指定位置的position-1位置的节点
     LINKLIST * preInsterNode= locbn(q, position-1);
    if(preInsterNode==NULL){//前一个结点为NULL,则插入的节点位置不存在
        printf("Loction position errer!");
    }else{
        LINKLIST *insterNode=(LINKLIST *)malloc(sizeof(LINKLIST));
        //2.判断查插入的节点是否为NULL,为NULL,则插入失败
        if(insterNode==NULL){
            printf("inster node is NULL");
        }else{
            insterNode->data=position;
            //3.将插入的结点的指针域指向插入位置的后一个结点
            insterNode->next=preInsterNode->next;
            //4.将插入结点位置的前一个指针域指向插入插入的节点;
            preInsterNode->next=insterNode;

            printf("inster success\n");
        }
    }
    return q;

}

在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断

#include <stdio.h>
#include "Link.h"
int main(int argc, const char * argv[]) {

    LINKLIST *SQ=testLinkList();
    //插入
    printf("插入结点\n");
    showLinkList(SQ);
    LINKLIST *insterAfterList= insterByPosition(SQ, 2);
    showLinkList(insterAfterList);
}

打印结果:

插入结点
list=[-1,1,2,3,4,5,6,7,8,9,10]
inster success
list=[-1,1,2,2,3,4,5,6,7,8,9,10]

7.删除

link.h 声明方法

/* 删除指定位置的节点 */
LINKLIST * delete(LINKLIST *Q,int index);

link.c 实现方法

LINKLIST * delete(LINKLIST *Q,int index){
    LINKLIST *p;
    p=Q;
    LINKLIST *preNode,*deleteNode;
    //1.判断链表的长度是否小于要删除节点的位置,如果小于,则表示链表中不存在此节点,否则就存在
    if(lenll(p)<index){
        printf("Location error!\n");
    }else{
        //2.获取删除节点的前一个结点
        preNode=locbn(Q, index-1);
        //3.通过前一个结点找到要删除的节点,即:删除节点的下一个节点
        deleteNode=preNode->next;
        //4.然后把删除节点的指针域赋给了删除节点前一个节点的指针域
        preNode->next=deleteNode->next;
        //5.同时要释放删除节点的
        free(deleteNode);
        deleteNode=NULL;
        printf("Locatio delete success!\n");
    }

    return p;
}

在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断

#include <stdio.h>
#include "Link.h"
int main(int argc, const char * argv[]) {

    LINKLIST *SQ=testLinkList();
    //删除
      printf("删除某个结点\n");
      showLinkList(SQ);
      LINKLIST *deleteAfterList= delete(SQ, 5);
      showLinkList(deleteAfterList);
}

打印结果:

删除某个结点
list=[-1,1,2,3,4,5,6,7,8,9,10]
Locatio delete success!
list=[-1,1,2,3,4,6,7,8,9,10]

8.合并

link.h 声明方法

/* 合并A和B,将B合并到A链表后面 */
LINKLIST *conll(LINKLIST *A,LINKLIST *B);

link.c 实现方法


LINKLIST *conll(LINKLIST *A,LINKLIST *B){
    LINKLIST *conP;
    conP=A;
    //1.判断要合并的B是否为BULL,和指针域是否为NULL,因为链表一般有一个头结点,应该查找从首节点开始合并
    if(B==NULL || B->next==NULL){
        return conP;
    }
    //2.如果A节点为NULL,那么也不能拼接
    if(A==NULL){
        return B;
    }
    //3.查找A链表的终结点
    while (A->next!=NULL) {
        A=A->next;
    }
    //4.将B插入到conP的最后面
    A->next=B->next;
    //5.释放B链表
    free(B);

    printf("合并成功\n");
    return conP;
}

在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断

#include <stdio.h>
#include "Link.h"
int main(int argc, const char * argv[]) {

   //合并节点
    printf("合并链表\n");
    //创建两个链表
    LINKLIST *A=testLinkList();
    LINKLIST *B=testLinkList();
    //展示要合并链表的节点
    showLinkList(A);
    showLinkList(B);
    //合并
    LINKLIST *AB= conll(A, B);

    //展示合并后的链表
    showLinkList(AB);
}

打印结果:

合并链表
list=[-1,1,2,3,4,5,6,7,8,9,10]
list=[-1,1,2,3,4,5,6,7,8,9,10]
合并成功
list=[-1,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10]

释放某个对象的方法,使用free()方法,则要引入:

#include <stdlib.h>


这是对链表的基本操作,大家有好的建议,请大家提出,互相学习和进步.
源码下载

  • 单链表基本操作2
    • 公共结构体
    • 模拟测试链表
    • 展示链表数据
    • 定位
      • 1按号定位
      • 2按值定位
    • 求链表长度
    • 插入
    • 删除
    • 合并

你可能感兴趣的:(链表,单链表,存储结构,结构)