数据结构之单链表
来源:互联网 发布:零基础学算法进制 编辑:程序博客网 时间:2024/05/22 10:34
链表:存储结构的一种,包含两个部分,数据域和指针域,相对于顺序存储结构来说,插入和删除的算法时间复杂度只为O(1).
定义:
//定义typedef struct Node *LinkList; //linkList,指针指向每一个元素typedef struct Node{ //每个元素的构成 ElemType data; //数据域 struct Node *next; //指针域 }Node;
注意:假设结点p表示一个结点A,那么p->next表示的下一个结点B,p->next也表示结点A的指针域,故,指针域存放的是指向下一个结点的指针。
以下为简单的C语言实现:
#include "stdio.h" #include "string.h"#include "ctype.h" #include "stdlib.h" #include "io.h" #include "math.h" #include "time.h"#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define MAXSIZE 20 /* 存储空间初始分配量 */typedef int Status;typedef int ElemType;//定义typedef struct Node *LinkList; //linkList,指针指向每一个元素typedef struct Node{ //每个元素的构成 ElemType data; //数据域 struct Node *next; //指针域 }Node; //初始化Status InitList(LinkList *L){ *L = (LinkList)malloc(sizeof(Node)); //产生头结点,使得L指向分配到的头结点 if(!(*L)){ //如果分配失败 return ERROR; } (*L)->next = NULL;//指针域为空 return OK; } //获取第几个元素 Status GetElem(LinkList L,int i,ElemType *e){ int j; LinkList p; /* 声明一结点p */ p = L->next; /* 让p指向链表L的第一个结点 */ j = 1; /* j为计数器 */ while (p && j<i) /* p不为空或者计数器j还没有等于i时,循环继续 */ { p = p->next; /* 让p指向下一个结点 */ ++j; } if ( !p || j>i ) return ERROR; /* 第i个元素不存在 */ *e = p->data; /* 取第i个元素的数据 */ printf("第%d元素为%d\n",i,*e); return OK;}//判断是否为空Status isEmptyList(LinkList L){ if(L->next){ return 1; }else{ return 0; }} //获取链表的长度int ListLength(LinkList L){ int i=0; LinkList p ; p = L->next; while(p){ i++; p = p->next; } return i;} //遍历链表 Status ListVisit(LinkList L){ LinkList p = L->next; printf("该链表的元素为:\n"); while(p){ printf("%d ",p->data); p = p->next; } printf("\n"); return OK; }//创建表,两种方法,头插法和尾插法 //头插法,在每一个头的开始不段插入,例如我们插入0-9,那么输出的结果就是9-0 void CreateListHead(LinkList *L,int n){ LinkList p; int i; srand(time(0)); *L = (LinkList)malloc(sizeof(Node)); (*L)->next = NULL; //先建立一个带头结点的单链表 for(i=0;i<n;i++){ p = (LinkList)malloc(sizeof(Node)); //新结点 p->data = rand()%100+1; //随机生成100以内的数字 p->next = (*L)->next; (*L)->next = p; //插入到头结点 ,即就是插入操作 } }//尾插法 ,最末尾元素后面插入,插入0-9 输出0-9 void CreateListTail(LinkList *L,int n){ LinkList p,r; int i; srand(time(0)); *L = (LinkList)malloc(sizeof(Node)); r = *L; //r指向链表 for(i=0;i<n;i++){ p = (Node *)malloc(sizeof(Node)); p->data = rand()%100+1; r->next = p; /* 将表尾终端结点的指针指向新结点 */ r = p; //将r赋值为新节点,下次指向的时候也就是把r指向了最末尾的结点,那么r也就是最末尾的结点 } r->next = NULL; //表示当前链表结束 } //重置表,也就是一个个结点的释放 Status ListClear(LinkList *L){ LinkList p,q; p = (*L)->next; while(p){ q = p->next; //每一次指向然后释放 free(p); p = q; // 释放后 重新赋给其原来的q结点的位置 } (*L)->next = NULL; //头结点指针域赋值为空 printf("清空完成\n"); return OK;}//查找表中元素int LocateEle(LinkList L,ElemType e){ int i=0; LinkList p; p = L->next; //指向链表,也就会指向头结点 while(p){ i++; if(p->data == e){ printf("元素%d在第%d个位置\n",e,i); return i; } p = p->next; } return 0;}//插入元素到表Status ListInsert(LinkList *L,int i,ElemType e){ int j; LinkList p,s; //创建两个结点p s p = *L; //指向一个链表 j=1; //查找到第i个结点 while( p &&j<i){ p = p->next; ++j; } if(!p || j>i){ return ERROR; } s = (LinkList)malloc(sizeof(Node)); //为新插入的分配一个结点 s->data = e; s->next = p->next; //将原来p的后继结点赋给s的 后继 p->next = s; //将s赋给p的后继 ,注意以上两条语句的位置不能倒置 return OK;} //删除表中元素 Status ListDelete(LinkList *L,int i,ElemType *e){ int j; LinkList p,q; p = *L; j=1; while(p->next &&j<i){ p = p->next; ++j; } if(!(p->next) || j>i){ return ERROR; } q = p->next; //先将p的后继赋给一个我们设置为q的结点,这个结点就是我们要删除的 p->next = q->next; //将原来q的后继赋给p的后继 *e = q->data; //将要删除的元素的值赋给*e printf("删除的元素为%d:\n",*e); free(q); //记得free return OK;}int main(){ LinkList L; ElemType e; Status i; int j,k; //初始化链表 i = InitList(&L); printf("初始化完成后插入的链表为\n"); for(j=1;j<=5;j++){ ListInsert(&L,1,j); } ListVisit(L); //插入单个元素 ListInsert(&L,2,100); e = 100; LocateEle(L,e); ListVisit(L); //删除元素 ListDelete(&L,2,&e); ListVisit(L); //获取第几个元素 GetElem(L,5,&e); //清空重置 ListClear(&L); ListVisit(L); //头插法 CreateListHead(&L,10); ListVisit(L); //尾插法 CreateListTail(&L,10); ListVisit(L); return 0;}
0 0
- 数据结构学习之单链表
- java数据结构之单链表
- 数据结构之单链表
- 数据结构学习之单链表
- 数据结构之单链表反转
- 数据结构之单链表
- 数据结构之, 单链表
- 数据结构之单链表
- 数据结构之单链表
- C++数据结构之单链表
- C++数据结构之单链表
- 数据结构之单链表
- 数据结构之单链表
- 大话数据结构之单链表
- C数据结构之单链表
- 数据结构基础之单链表
- javascript 数据结构 之 单链表
- 数据结构之单链表操作
- 【OpenCV入门教程之一】 安装OpenCV:OpenCV 3.0、OpenCV 2.4.8、OpenCV 2.4.9 +VS 开发环境配置
- 集合名称阅读技巧
- Linux消息队列的使用:实现server和client相互发送消息
- 大数模板
- 三方开源库(具体的地址请看)
- 数据结构之单链表
- 《Matlab在数学建模中的应用》笔记2-非线性规划&整数规划
- (OK) using persistant storage in linux kernel - /sys/fs/pstore/console-ramoops
- 【jsp/servlet】jsp数据交互(一)
- poj3281 Dining 最大流
- android 图片加载和缓存开源项目 Picasso
- nginx定位到laravel下
- 130道C#面试题
- 在 Ubuntu 16.04 上安装 LEMP 环境之图文向导