数据结构-链表

一、什么是链表

链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表这种存储方式,其元素个数是不受限定的,当进行添加元素的时候存储的个数就会随之改变。

二、链表的分类

  1. 循环 -带头/不带头--单链表/双向链表
  2. 非循环 -带头/不带头--单链表/双向链表
typedef struct LNode

{

int data;

strruct LNode *next;

}LinkNode;

 

 

此处LinkNode 为变量名。

 struct LNode

{

int data;

strruct LNode *next;

}LinkNode;

 

 

此处LinkNode 为类型名。

三、单链表特点

访问下一个元素后没法访问他的前驱。

四、单链表的基本操作———初始化,插入、删除、遍历、查询。

1.准备工作

头文件

#include "stdio.h"                
#include "stdlib.h"                //提供malloc()和free()
#include "string.h"                //提供strcpy()等

 malloc函数:动态内存分配函数

分配类型 *)malloc(分配元素个数 *sizeof(分配类型))
如果成功,则返回该空间首地址,该空间没有初始化,如果失败,则返回0

a=(char*)malloc(100*sizeof(char));

 free函数

free ()

free的功能:释放ptr指向的存储空间。被释放的空间通常被送入可用存储区池,以后可在调用malloc、realloc以及calloc函数来再分配。
就是说free掉以后,可以这段内存就可以被再分配,但是不会清空内容。

地址是不可能被删掉的,free只是告诉系统,这块内存不需要了,系统可以拿来做别的事。这块内存被释放之后暂时还没有其他程序访问这块内存,所以之前的数据还在,读也能读出来,但这样是不安全的,这次是这个结果,下一次就不一定了。c要求严谨,释放之后的内存就不要再用了

2.基本操作
创建结构体

struct Node
{
    int a;//数据域 
    struct Node* next; //指针域 
 } ;
 

全局定义链表头尾指针,方便调用

struct Node *head =NULL;
struct Node *end=NULL;
#include <iostream>
#include <cstdio>  
#include <stdlib.h>  

using namespace std;

typedef int ElemType;
typedef struct Node  //用结构体定义结点
{
    ElemType data;
    struct Node *next;
}Node, *LinkedList;
//把struct Node *定义为新类型LinkList,是一个结构体的指针。  
void InitLinkedList()   //初始化
{
    Node* L;  //定义一个头结点
    L = (Node *)malloc(sizeof(Node));//头结点申请地址
    if (L == NULL)
        printf("申请空间失败");
    L->next = NULL;
}
LinkedList CreateLinkedListHead(int n)//头插法  
{
    int i;
    int x;
    Node *L;
    L = (Node *)malloc(sizeof(Node));
    L->next = NULL;
    printf("输入元素:");
    for (i = 0; i<n; i++)
    {
        Node *p; //要插入的结点
        p = (Node *)malloc(sizeof(Node));
        scanf("%d", &x);
        p->data = x;
        p->next = L->next;
        L->next = p;
    }
    return L;
}
LinkedList CreateLinkedListTail(int n)//尾插法  
{
    int x;
    Node *L;
    L = (Node *)malloc(sizeof(Node));
    L->next = NULL;
    Node *r;
    r = L;
    printf("输入元素:");
    while (n--)
    {
        scanf("%d", &x);
        Node *p;
        p = (Node *)malloc(sizeof(Node));
        p->data = x;
        r->next = p;
        r = p;//之后的循环遇到r就是等同于p r->next就是p->next
    }
    r->next = NULL;
    return L;
}
void InsertLinkedList(LinkedList L, int i, ElemType x)//插入元素  i为插入位置 x为插入元素
{
    LinkedList p;
    p = L;//把链表的头结点赋值给p
    int j;
    j = 1;
    while (j<i)
    {
        p = p->next;
        j++;
    }
    Node *s;  //定义插入的结点
    s = (Node *)malloc(sizeof(Node));
    s->data = x;
    s->next = p->next;
    p->next = s;

}
void output(LinkedList L)//遍历
{
    Node *p;
    for (p = L->next; p != NULL; p = p->next)
    {
        printf("%d", p->data);
    }
}
void deleteLinkedList(LinkedList L, int i)//删除i位置上的元素  
{
    int j;
    LinkedList p, q;
    p = L;
    j = 1;
    while (j<i)
    {
        p = p->next;
        j++;
    }
    q = p->next;
    p->next = p->next->next;
    free(q);
}


int GetElem(LinkedList L, int i)//获取元素  
{
    ElemType e;
    int j;
    LinkedList p;
    p = L->next;
    j = 1;
    while (p && j<i)
    {
        p = p->next;
        j++;
    }
    if (!p || j > i)
    {
        printf("第%d个节点不存在\n", i);
        return 0;
    }
    else 

    e = p->data;
    return e;
}


 int getlength(LinkedList L)//求单链表长度(遍历了)
 {
    LinkedList p;
    int length = 0;
    p = L->next;//p指向第一个节点;
       while (p)
       {
           printf("单链表的数据为%d\n", p->data);
           length++;
           p = p->next;
         
        }
       return length;
    
}
void ClearList(LinkedList L)
{
    LinkedList p, q;
    p = L->next;
    while (p)
    {
        q = p->next;
        free(p);
        p = q;
    }
    L->next = NULL;
}
int main()
{
    int n;
    int i;
    int x;
    LinkedList H;
    printf("输入单链表的长度(头插法):");
    scanf("%d", &n);
    H = CreateLinkedListHead(n);
    output(H);
    printf("\n");
    printf("输入单链表的长度(尾插法):");
    scanf("%d", &n);
    H = CreateLinkedListTail(n);
    output(H);
    printf("\n");
    printf("单链表长度为%d", getlength(H));
    printf("\n");
    printf("输入要获取哪一位置的元素:");
    scanf("%d", &i);
    printf("%d\n", GetElem(H, i));
    printf("输入要插入的元素e与位置i:");
    scanf("%d %d", &x, &i);
    InsertLinkedList(H, i, x);
    output(H);
    printf("\n");
    printf("输入要删除哪一位置上的元素:");
    scanf("%d", &i);
    deleteLinkedList(H, i);
    output(H);
    printf("\n是否要整表删除1/0?\n");
    scanf("%d", &x);
    if (x == 1)
    {
        ClearList(H);
        printf("单链表为:");
        output(H);
    }
    else
    {
        printf("单链表仍为:");
        output(H);
    }
    system("pause");
    return 0;
}

 

posted @ 2020-09-21 09:17  Icarus0320  阅读(105)  评论(0)    收藏  举报