数据结构——单链表

单链表简介

       链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

链接存储方式

1.用一组任意的存储单元来存放线性表的结点

2.链表中结点的逻辑次序和物理次序不一定相同,在存储每个结点值的同时,还必须存储指示起后继节点的地址信息。

链表的结点结构

┌───┬───┐
│data │next │
└───┴───┘
data域--存放结点值的数据域。
next域--存放结点的直接后继的地址(位置)的 指针域(链域)。
注意:①链表通过每个结点的指针域将链表的n个结点安妮逻辑循序连接在一起的。
②每个结点只有一个指针域的链表称为单链表。
③链表由头结点唯一确定,单链表可以用头指针的名字来命名。
④尾结点无后继结点,故尾结点的指针域为NULL。
typedef struct node{
        int data;    //数据域
        struct node * next; //指针域
    }Node, *pNode; //别名

单链表的常见操作

1.创建链表

pNode createList(){
    int len, val;  //len存放链表长度,val存放结点数据值

    pNode pHead = (pNode)malloc(sizeof(Node));  //给头结点动态分配内存
    if(pHead == NULL){    //判断分配内存是否成功
        printf("动态分配内存失败");
        exit(-1);
    }
    pNode pTail = pHead; //定义尾结点
    pTail->next = NULL;  //尾结点无后继指针
    printf("请输入创建链表长度len:");
    scanf("%d", &len);

    for(int i=0; i<len; i++){
        pNode pNew = (pNode)malloc(sizeof(Node)); //定义新结点,动态分配内存
        if(pNew == NULL){
            printf("动态分配内存失败");
            exit(-1);
        }
        printf("请输入第%d个结点数值:", i+1);
        scanf("%d", &val);

        pNew->data = val; //新结点数据域存放数值
        pTail->next = pNew;  //令尾结点指针指向新结点
        pNew->next = NULL;   //当尾结点指向新结点时,新结点成为最后一个结点,其指针域应为空
        pTail = pNew; //令尾结点指向最后一个结点
    }
    return pHead;

}
2. 遍历链表
void traversalList(pNode p){
   	 while(p->next){  //判断结点的指针域是否为空
       	    p = p->next;   //指向下一个结点
           printf("%d ", p->data);  //打印结点数值
         }
         printf("\n");
     }
3.计算链表长度
int length(pNode p){
   	 pNode L = p->next; //定义临时结点指向首结点
         int len = 0; //存放链表长度
         while(L){  //判断首结点是否存在
           len++;
           L = L->next;
           }
           return len;
      }
4.判断链表为空
bool isEmpty(pNode p){  
         if(!(p->next))    //判断首结点是否为空
             return true; // 
         else
             return false;
      }
5.排序(从小到大)
void sortList(pNode p){
          int len = length(p);  //存放链表长度  
          for(int i=0; i<len-1; i++){   
              p = p->next;  //外层每循环一次,指向下一个结点
              pNode q = p->next;  //定义新结点指向一个结点的下一个结点
              for(int j=i+1; j<len; j++){  //一个结点与这个结点后面的每个结点依次比较
                 if(p->data > q->data){  //如果这个结点小于这个结点后面任意一个结点,互换值
                    int temp = p->data;
                    p->data = q->data;
                    q->data = temp;
                 }
                 q = q->next;   
              }
          }
}
6插入(第n个结点的前面)
void insertList(pNode p, int pos, int val){
          int i=0;
          pNode pNew = (pNode)malloc(sizeof(Node));   //定义结点
          if(!pNew){
              printf("动态分配内存失败");
              exit(-1);
          }
          pNew->data = val;  //存放插入数据
          while(i<pos-1 && p->next){   //寻找要插入结点的前一个结点
              p = p->next;
              i++;
          }
          if(i>pos-1 || !(p->next)){   //判断指针指向的位置是否正确
             return;
          }
          else{
             pNew->next = p->next;
             p->next = pNew;
         }
    }
7.删除
void deleteList(pNode p, int pos){
          int i = 0;
          while(i<pos-1 && p->next){  //寻找删除结点的前一个结点
              p = p->next;
              i++;
          }
          if(i>pos-1 || !(p->next)){  //判断指针指向的位置是否正确
              return;
           }
           else{
              pNode q = p->next;  //定义临时结点错放被删除结点
              p->next = q->next;  //指针指向的结点的指针域存放被删除结点的后继结点
              free(q);  //删除结点
               q = NULL; 
          }
     }

完整代码

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

typedef struct node{
    int data;
    struct node * next;
}Node, *pNode;

pNode createList();
void traversalList(pNode p);
int length(pNode);
bool isEmpty(pNode);
void sortList(pNode);
void insertList(pNode, int, int);
void deleteList(pNode, int);

int main(void){
    pNode p = createList();
    return 0;
}

pNode createList(){
    int len, val;

    pNode pHead = (pNode)malloc(sizeof(Node));
    if(pHead == NULL){
        printf("动态分配内存失败");
        exit(-1);
    }
    pNode pTail = pHead;
    pTail->next = NULL;
    printf("请输入创建链表长度len:");
    scanf("%d", &len);

    for(int i=0; i<len; i++){
        pNode pNew = (pNode)malloc(sizeof(Node));
        if(pNew == NULL){
            printf("动态分配内存失败");
            exit(-1);
        }
        printf("请输入第%d个结点数值:", i+1);
        scanf("%d", &val);

        pNew->data = val;
        pTail->next = pNew;
        pNew->next = NULL;
        pTail = pNew;
    }
    return pHead;

}

void traversalList(pNode p){
    while(p->next){
        p = p->next;
        printf("%d ", p->data);
    }
    printf("\n");
}

int length(pNode p){
    pNode L = p->next;
    int len = 0;
    while(L){
        len++;
        L = L->next;
    }
    return len;
}

bool isEmpty(pNode p){
    if(!(p->next))
        return true;
    else
        return false;
}

void sortList(pNode p){
    int len = length(p);
    for(int i=0; i<len-1; i++){
        p = p->next;
        pNode q = p->next;
        for(int j=i+1; j<len; j++){
            if(p->data > q->data){
                int temp = p->data;
                p->data = q->data;
                q->data = temp;
            }
            q = q->next;
        }
    }
}
void insertList(pNode p, int pos, int val){
    int i=0;
    pNode pNew = (pNode)malloc(sizeof(Node));
    if(!pNew){
        printf("动态分配内存失败");
        exit(-1);
    }
    pNew->data = val;
    while(i<pos-1 && p->next){
        p = p->next;
        i++;
    }
    if(i>pos-1 || !(p->next)){
        return;
    }
    else{
        pNew->next = p->next;
        p->next = pNew;
    }
}
void deleteList(pNode p, int pos){
    int i = 0;
    while(i<pos-1 && p->next){
        p = p->next;
        i++;
    }
    if(i>pos-1 || !(p->next)){
        return;
    }
    else{
        pNode q = p->next;
        p->next = q->next;
        free(q);
        q = NULL;

    }

}











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值