#include <stdio.h>
#include <stdlib.h> /**
* 含头节点单链表定义及基本操作
*/ //基本操作函数用到的状态码
#define TRUE 1;
#define FALSE 0;
#define OK 1;
#define ERROR 0;
#define INFEASIBLE -1; //当不可行时
const int OVERFLOW = -2; //当溢出时 //Status是新定义的一种函数返回值类型,其值为int型,意义为函数结果 状态码
typedef int Status;
//定义一种 数据元素 类型,为表示方便,定义为char型
typedef char ElemType;
//单链表定义
typedef struct Lnode {
ElemType data; //数据域,这里是char类型变量
struct Lnode *next; //指针域,结构体类型指针
} Lnode, *LinkList;
/**
* 注:方式 Lnode* p 和 LinkList L 定义出的指针p、L类型等价,
* 但一般用前者定义指向元素节点的指针,用后者定义指向链表的指针
*/ //基本操作1:单链表初始化
Status InitList(LinkList *list) {
(*list)=(LinkList)malloc(sizeof(Lnode));
(*list)->next=NULL;
return OK;
} //基本操作2:判断单链表是否为空
int IsEmpty(LinkList list) {
if(list->next){
return FALSE;
} else {
return TRUE;
}
} //基本操作3:单链表销毁
Status DestroyList(LinkList *list) {
Lnode *p; //工作指针
while(*list){
p=(*list);
(*list)=(*list)->next;
free(p);
}
return OK;
} //基本操作4:单链表清空
Status ClearList(LinkList *list) {
Lnode *p,*q;
p=(*list)->next; //清空结点
while(p){
q=p->next;
p=NULL;
p=q;
} //清空头结点
(*list)->next=NULL;
return OK;
} //基本操作5:求单链表长
int GetLength(LinkList list){
Lnode *p;
int len=0;
p = list->next; //p先指向首元结点
while(p){
len++;
p=p->next;
}
return len;
} //基本操作6:根据结点索引i获取相应位置元素的内容
Status GetElem(LinkList list,int i,ElemType *elem) {
Lnode *p; //工作指针
int j=0; //计数器
p=list->next; //p指向第一个结点
while(p&&j<i){
p=p->next;
j++;
}
/**
*正常情况下此时:j=i(到达目标点,找到)或者p->NULL(到达表尾,仍未找到); 但若i<1,此时i<j=1,也未找到;
*/
if(!p||i<j) return ERROR;
*elem=p->data;
return OK;
} //基本操作7:查找与目标元素值相同的元素结点,返回元素地址 ,若不存在,返回NULL地址
Lnode* LocateElemAddress(LinkList list,ElemType elem) {
Lnode *p;
p=list->next;
while(p&&p->data!=elem){
p=p->next;
}
return p;
} //基本操作8:查找与目标元素值相同的元素结点,返回逻辑索引(1~n),若不存在,返回0
int LocateElemIndex(LinkList list,ElemType elem) {
Lnode *p;
int j=1;
p=list->next;
while(p&&p->data!=elem) {
j++;
p=p->next;
}
if(p) return j;
return 0;
} //基本操作9:插入新元素数据到指定位置。(i为逻辑位置)
Status ListInsert(LinkList *list,int i,ElemType elem){
if(i<1) return ERROR; //插入位置序号小于1
Lnode *p;
int j=0; //计数器
p=*list;
//先找到第i-1个结点
while(p&&j<i-1){
j++;
p=p->next;
}
//这里正常情况,j=i-1,p指向第i-1个结点;否则,j=表长+1,p->NULL if(!p) return ERROR; //构造新结点
Lnode *new_node;
new_node=(Lnode*)malloc(sizeof(Lnode));
new_node->data= elem;
//插入到链表
new_node->next=p->next;
p->next=new_node;
return OK;
} //基本操作10:删除链表第i个结点,被删除的结点数据保存在实参elem
Status ListDelete(LinkList *list,int i,ElemType *elem) {
Lnode *p,*q;
int j=0;
p=*list;
while(p->next&&j<i-1){
p=p->next;
j++;
}
if(!(p->next)||j>i-1) return ERROR; //删除位置不合理 q=p->next; //q指向被删除的结点 //连接链表
p->next=p->next->next; //或者:p->next=q->next; //保存删除结点的数据
*elem=q->data; //释放内存
free(q);
return OK;
} //基本操作11:头插法建立链表,假设我们的数据保存在ElemType类型的数组中(且头结点已建立)。
Status CreateList_H(LinkList *list,ElemType arrData[],int length) {
int j;
for(j=length-1;j>=0;j--){
//新建结点
Lnode *node;
node=(Lnode*)malloc(sizeof(Lnode));
node->data=arrData[j];
node->next=NULL;
//插入为1号结点
node->next=(*list)->next;
(*list)->next=node;
}
return OK;
} //基本操作12:尾插法建立链表。
Status CreateList_R(LinkList *list,ElemType arrData[],int length) {
int j;
Lnode *r; //尾指针
r=*list;
for(j=0;j<length;j++) {
Lnode *node;
node=(Lnode*)malloc(sizeof(Lnode));
node->data=arrData[j];
node->next=NULL; r->next=node; //node插入到表尾
r=node; //r指向尾结点
}
return OK;
} //基本操作13:链表元素遍历输出
Status ListTraverse(LinkList list) {
Lnode *p;
p=list;
int j=0;
printf("逻辑索引: 结点数据:\n");
while(p->next){
j++;
p=p->next;
printf(" %d %c\n",j,p->data);
}
return OK;
} int main(void){
//定义一个链表(用指针list1表示一个链表)
LinkList list1; //链表初始化
Status initResultCode=InitList(&list1);
printf("list1初始化结果:%d\n",initResultCode); //给链表添加结点 (下面将用函数实现:头插法、尾插法)
//结点初始化
Lnode *node1,*node2,*node3;
node1=(Lnode*)malloc(sizeof(Lnode));
node2=(Lnode*)malloc(sizeof(Lnode));
node3=(Lnode*)malloc(sizeof(Lnode));
node1->data='Y';
node2->data='C';
node3->data='L';
node1->next=NULL;
node2->next=NULL;
node3->next=NULL;
//结点连接
list1->next=node1;
node1->next=node2;
node2->next=node3;
node3->next=NULL;
//打印初始结点
printf("结点1的值:%c\n",list1->next->data);
printf("结点2的值:%c\n",list1->next->next->data);
printf("结点3的值:%c\n",list1->next->next->next->data); //为空?
/*
int isNull=IsEmpty(list1);
printf("为空?:%d\n",isNull);
*/ //销毁
/*
Status destroyResultCode = DestroyList(&list1);
printf("销毁结果状态码为:%d\n",destroyResultCode); //1
//测试
//printf("销毁后结点1的值:%c\n",list1->next->data); //Nothing
*/ //清空
/*
Status clearResultCode = ClearList(&list1);
//测试
printf("清空结果状态码为%d\n",clearResultCode); //1
//printf("清空后结点1的值:%c\n",list1->next->data); //Nothing
*/ //获得表长
/*
int listLength = GetLength(list1);
printf("表长:%d\n",listLength);
*/ //用 中间元素elemx 保存索引到的元素的值
/*
ElemType elemx;
Status getElemResult = GetElem(list1,3,&elemx);
printf("得到元素?:%d\n",getElemResult);
printf("得到元素值:%c\n",elemx);
*/ //查找元素结点,返回元素地址
/*
ElemType elemTarget1='L';
Lnode *address = LocateElemAddress(list1,elemTarget1);
printf("查找到元素的地址:0x%p\n",address);
*/ //查找元素结点,返回元素逻辑索引
/*
ElemType elemTarget2='L';
int index=LocateElemIndex(list1,elemTarget2);
printf("查找到元素的索引:%d\n",index);
*/ //插入
/*
ElemType elemInserted='T';
Status insertResultCode = ListInsert(&list1,2,elemInserted);
printf("插入结果状态码:%d\n",insertResultCode);
//遍历测试
ListTraverse(list1);
*/ //删除结点,保存到删除的数据
/*
ElemType deletedElem;
Status deleteResultCode=ListDelete(&list1,2,&deletedElem);
printf("删除结果状态码:%d\n",deleteResultCode);
printf("被删除结点的数据:%c\n",deletedElem);
//遍历测试
ListTraverse(list1);
*/ /**
* 链表的建立:头插法、尾插法。
*/
//产生数据并保存到数组
ElemType data1='A',data2='B',data3='C',data4='D',data5='E',data6='F';
ElemType waitInserted[]={
data1,
data2,
data3,
data4,
data5,
data6,
};
//获得数组长度
int arrLength=sizeof(waitInserted)/sizeof(waitInserted[0]); //头插法建立链表
/*
LinkList list2; //定义新链表
InitList(&list2); //链表初始化,建立头结点
//由数组数据建立链表
Status createListResult1 = CreateList_H(&list2,waitInserted,arrLength);
printf("建表结果状态码:%d\n",createListResult1);
//遍历测试
ListTraverse(list2);
*/ //尾插法建立链表
/*
LinkList list3; //定义新链表
InitList(&list3); //链表初始化,建立头结点
//由数组数据建立链表
Status createListResult2 = CreateList_R(&list3,waitInserted,arrLength);
printf("建表结果状态码:%d\n",createListResult2);
//遍历测试
ListTraverse(list3);
*/ printf("\nEND!");
return 0;
}

单链表及基本操作(C语言)的更多相关文章

  1. PHP单链表的基本操作

    链表的实现 数据结构第一个就是链表了,链表分为两种有直接的数组形式的顺序链,这里不讨论,什么array_push(),array_pop(),函数基本能满足日常的需求,但报告老板,我就是想装个X 上代 ...

  2. 用Java实现单链表的基本操作

    笔试题中经常遇到单链表的考题,下面用java总结一下单链表的基本操作,包括添加删除节点,以及链表转置. package mars; //单链表添加,删除节点 public class ListNode ...

  3. 数据结构—单链表(类C语言描写叙述)

    单链表 1.链接存储方法 链接方式存储的线性表简称为链表(Linked List). 链表的详细存储表示为: ① 用一组随意的存储单元来存放线性表的结点(这组存储单元既能够是连续的.也能够是不连续的) ...

  4. 不带头结点的单链表(基于c语言)

    本篇文章的代码大多使用无头结点的单链表: 相关定义: #include <stdio.h> #include <stdlib.h> #include <assert.h& ...

  5. 用java简单的实现单链表的基本操作

    package com.tyxh.link; //节点类 public class Node { protected Node next; //指针域 protected int data;//数据域 ...

  6. 单链表的基本操作--c++

    #include <iostream> //实现单链表的建立,测长和打印 #include <string> using namespace std; struct node ...

  7. 逆置单链表(基于c语言)

    直接插入全部代码:(reverseLinklist函数是逆置操作) #include <stdio.h> #include <stdlib.h> #include <as ...

  8. 【C++/数据结构】单链表的基本操作

    #pragma once #ifndef _CLIST_H_ #define _CLIST_H_ #include <iostream> #include <assert.h> ...

  9. 单链表 C语言 学习记录

    概念 链接方式存储 链接方式存储的线性表简称为链表(Linked List). 链表的具体存储表示为: 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的). 链表中 ...

随机推荐

  1. CentOS7安装配置 NFS

    一.NFS 简介 NFS(Network File System)即网络文件系统,它允许网络中的计算机之间通过TCP/IP网络共享资源.在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端N ...

  2. HDU 6623 Minimal Power of Prime(思维)题解

    题意: 已知任意大于\(1\)的整数\(a = p_1^{q_1}p_2^{q_2} \cdots p_k^{q_k}\),现给出\(a \in [2,1e18]\),求\(min\{q_i\},q ...

  3. 使用Benchmark.NET测试代码性能

    今天,我们将研究如何使用Benchmark.Net来测试代码性能.借助基准测试,我们可以创建基准来验证所做的更改是否按预期工作并且不会导致性能下降. 并非每个项目都需要进行基准测试,但是如果您正在开发 ...

  4. 从GitHub Jobs! 看技术发展趋势! 程序员进阶必备!

    0. https://jobs.github.com/positions GitHub Jobs: 1. https://jobs.github.com/positions/38bb8dc8-b5b4 ...

  5. Github history viewer

    Github history viewer https://github.githistory.xyz/ https://github.com/pomber/git-history https://c ...

  6. modal 弹框遮罩层,滚动穿透bug 解决方案

    modal 弹框遮罩层,滚动穿透bug 解决方案 parent component 动态设置 lock css const computedClassName = classNames( 'activ ...

  7. Node.js & LTS

    Node.js & LTS 2020 https://nodejs.org/en/about/releases/ https://raw.githubusercontent.com/nodej ...

  8. SPC算力空投来袭!对话NGK!华盛顿金融特别报道

    近日华盛顿金融时报联合波士顿商业报等多家知名金融媒体专访了NGK. NGK代表马特彼得森就表示NGK在新的一年里将会继续以生态建设者为中心,以打造高倍币孵化器为目标,不断推进NGK项目的落地,踏踏实实 ...

  9. NGK数字钱包的特点是什么?NGK钱包的优点和缺点是什么?

    说起区块链数字资产,那就离不开谈到数字钱包.数字钱包不仅有资产管理的功能,还可以进行资产理财.资产交易,甚至能为公链DAPP导流. 对于NGK公链而言,其数字钱包已然成为了解NGK公链的基础条件.NG ...

  10. RocketMq灰皮书(三)------MQ使用

    RocketMq灰皮书(三)------MQ使用 在使用MQ之前,我们回顾一下前两篇博文的内容. 我们大致了解了RocketMQ的四个概念,分别是:Producer,Consumer,Message和 ...