线性表的链式表示

以下为操作链表的算法,该链表为动态单链表。

链表以头指针为索引,头指针指向头节点,头节点指向首节点,以此类推,直到尾节点。

头节点中不存放数据,只存放指向首节点的指针,

设置头节点的目的是为了方便对链表的操作,如果不设置头节点,而是直接由头指针指向首节点,

这样在对头指针后的节点进行插入删除操作时就会与其他节点进行该操作时有所不同,便要作为一种特殊情况来分析

操作系统:ubuntu

编译软件:gcc

结果截图:

源代码:

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

typedef struct Node
{
 int data;
 struct Node *pNext;
}NODE,*PNODE;  

PNODE create_list();
void traverse_list(PNODE);
bool is_empty(PNODE);
int length_list(PNODE);
void sort_list(PNODE);
bool insert_list(PNODE,int,int);
bool delete_list(PNODE,int,int *);
void clear_list(PNODE);  

int main(void)
{
 int len;
 int data_del;
 PNODE pHead = NULL;  

 //创建链表并遍历输出
  pHead = create_list();
 traverse_list(pHead);  

 //求链表长度,并输出
 len = length_list(pHead);
 if(!is_empty(pHead))
  printf("the length of the list is:%d\n",len);  

 //向链表中插入数据,并重新遍历输出
 if(insert_list(pHead,3,78))
  printf("insert succeed,");
 else
  printf("insert failed,");
 traverse_list(pHead);  

 //从链表中删除数据,并重新遍历输出
 //本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/
 if(delete_list(pHead,3,&data_del))
  {
    printf("delete succeed,the deleted data is:%d\n",data_del);
  }
 else
  printf("delete failed,");
 traverse_list(pHead);  

 //对链表排序,重新遍历输出
 sort_list(pHead);
 printf("After sorted,");
 traverse_list(pHead);   

 //清空链表,遍历输出(无数据输出)
 clear_list(pHead);
 printf("After cleared,");
 traverse_list(pHead);
 return 0;
}  

//子函数:创建一个链表,并返回头指针
PNODE create_list()
{
 int val;
 PNODE pHead =(PNODE)malloc(sizeof(NODE));
 PNODE pCurrent = pHead;
 pCurrent->pNext = NULL;
 if(NULL == pHead)
 {
  printf("pHead malloc failed!");
  exit(-1);
 }
 printf("Input first data(q to quit):");
 while(scanf("%d",&val)==1)
 {
  PNODE pNew = (PNODE)malloc(sizeof(NODE));
  if(NULL == pNew)
  {
   printf("pNew malloc failed!");
   exit(-1);
  }
  pNew->data = val;
  pCurrent->pNext = pNew;
  pNew->pNext = NULL;
  pCurrent = pNew;
  printf("Input next data(q to quit):");
 }
 return pHead;
}  

//子函数:遍历链表  

void traverse_list(PNODE pHead)
{
 PNODE pCurrent = pHead->pNext;
 printf("now dataes in the list are:\n");
 while(pCurrent != NULL)
 {
  printf("%d ",pCurrent->data);
  pCurrent = pCurrent->pNext;
 }
 printf("\n");
 return ;
}
//子函数:判断链表是否为空
bool is_empty(PNODE pNode)
{
 if(NULL == pNode->pNext)
  return true;
 else
  return false;
}  

//子函数:求链表长度(不计入头结点)
int length_list(PNODE pNode)
{
 int count = 0;
 PNODE pCurrent = pNode->pNext;
 while(pCurrent != NULL)
 {
  count++;
  pCurrent = pCurrent->pNext;
 }  

 return count;
}  

//子函数:冒泡法对链表排序
void sort_list(PNODE pHead)
{
 PNODE p,q;
 int temp;
 for(p=pHead->pNext;p!=NULL;p=p->pNext)
     for(q=p->pNext;q!=NULL;q=q->pNext)
  {
     if(p->data>q->data)
               {
    temp = p->data;
    p->data = q->data;
    q->data = temp;
        }
  }  

 return ;
}  

//子函数:在第pos个节点的后面插入一个新的节点,该节点中的数据为val
bool insert_list(PNODE pHead,int pos,int val)
{
 int i = 0;
 PNODE p = pHead;  

 //i为0时,p指向第0个节点(这里指没有实际数据的头节点,不计入链表节点总数),
 //i为1时,p指向第1个节点,i为几,p就指向第几个节点
 while(p!=NULL && i<pos)
 {
    p = p->pNext;
    i++;
 }  

 //当pos的值大于链表长度时或者pos<0时,便会出现这种情况
 if(i>pos || p==NULL)
    return false;  

 PNODE pNew = (PNODE)malloc(sizeof(NODE));
 if(NULL == pNew)
 {
    printf("pNew malloc failed!");
    exit(-1);
 }
 pNew->data = val;
 pNew->pNext = p->pNext;
 p->pNext = pNew;  

 return true;
}  

//子函数:删除第pos个节点,并将删除的数据保存在pData指针所指向的位置
bool delete_list(PNODE pHead,int pos,int *pData)
{
 int i = 0;
 PNODE p = pHead;  

 //p最终指向第pos个节点前面的节点,这里同样以头结点为第0个节点
 //如果下面两句分别改为while(p!=NULL && i<pos)和if(i>pos-1 || p==NULL),则p最终指向第pos个节点,
 //这样因为得不到第pos个节点前面的那个节点,因此无法将pos前后两个节点连结起来
 while(p->pNext!=NULL && i<pos)  

 {
    p = p->pNext;
    i++;
 }  

 //当pos的值大于链表长度时或者pos<1时,便会出现这种情况,第0个节点,即头结点是不能被删除的。
 if(i>pos-1 || p->pNext==NULL)
    return false;  

 PNODE q = p->pNext;
 *pData = q->data;
 p->pNext = p->pNext->pNext;
 free(q);
 q = NULL;
 return true;
}  

//子函数:清空链表,即使链表只剩下头节点(头节点中没有数据)
void clear_list(PNODE pHead)
{
 PNODE p = pHead->pNext;
 PNODE r = NULL;
 while(p != NULL)
 {
    r = p->pNext;
    free(p);
    p = r;
 }
 pHead->pNext = NULL;
 return ;
}

.

作者:csdn博客 兰亭风雨

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索链表
, int
, printf
, return
, 其他节点指针有值
, null
, 节点
, 指向
, 线性表排序
遍历子节点
线性表的链式存储结构、线性表的链式存储、线性表的链式存储代码、链式线性表的基本操作、线性表链式存储,以便于您获取更多的相关知识。

时间: 2024-10-29 08:26:47

线性表的链式表示的相关文章

大话数据结构二:线性表的链式存储结构(单链表)

1. 线性表的链式存储结构:指的是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的,这就意味着这些数据元素可以存在内存未被占用的任意位置. 2. 结点:结点由存放数据元素的数据域和存放后继结点地址的指针域组成. 1.)顺序存储结构中,每个数据元素只需要存数据元素的信息就可以了. 2.)链式存储结构中,除了要存储数据元素信息外,还要存储它的后继元素的存储地址. 3.)链表中第一个结点叫头结点,它的存储位置叫做头指针,它的数据域可以不存储任何信息,链表的最后一个结

数据结构教程 第八课 线性表的链式表示与实现

本课主题: 线性表的链式表示与实现 教学目的: 掌握线性链表.单链表.静态链表的概念.表示及实现方法 教学重点: 线性链表之单链表的表示及实现方法. 教学难点: 线性链表的概念. 授课内容: 一.复习顺序表的定义. 二.线性链表的概念: 以链式结构存储的线性表称之为线性链表. 特点是该线性表中的数据元素可以用任意的存储单元来存储.线性表中逻辑相邻的两元素的存储空间可以是不连续的.为表示逻辑上的顺序关系,对表的每个数据元素除存储本身的信息之外,还需存储一个指示其直接衙继的信息.这两部分信息组成数据

《数据结构与算法 C语言版》—— 2.3线性表的链式表示与实现

2.3线性表的链式表示与实现 线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任一元素,它的存储位置可用一个简单.直观的公式来表示.然而,从另一方面来看,这个特点也造成了这种存储结构的弱点:在作插入或删除操作时,需移动大量元素.本节我们将讨论线性表的另一种表示方法--链式存储结构,其特点是用一组地址任意的存储单元存储线性表中的数据元素.由于它不要求逻辑上相邻的元素在物理位置上也相邻,因此它没有顺序存储结构所具有的弱点,但同时也失去了顺序表随机存取的特点

线性表的链式表示和实现

一.前言     线性表的顺序存储结构特点是:逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中的任何一个元素.    缺点:在作插入删除操作时,需要移动大量元素. 二.链式存储结构     概念:它不要求逻辑上相邻的元素在物理位置上也相邻,因此它没有顺序存储结构所具有的弱点,但同时也失去顺序表可随机存取的优点. 三.线性链表     存储空间可以连续也可以不连续.为了表示ai和ai+1的逻辑关系,对数据元素ai来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直

艾伟_转载:C#版数据结构之--线性表的链式存储(单链表)

1.单链表的定义和由来: 链表是用一组地址可能连续也可能不连续的存储单元来存储线性表中的数据元素,在存储数据元素时,除了要存储数据元素本身之外,还要存储与它相邻的数据元素的地址信息,这两部分组成了线性表中一个数据元素的映像,称之为"结点",存储数据元素本身的部分称之为:数据域,存储相邻数据元素地址的部分称之为:地址域,所有节点通过地址域链接起来,像一个链条,故用此种方式存储的线性表称之为:链表.如果节点的地址域只存储了数据元素的直接后继的存储地址,则称这种链表为:单链表. 与数序表相比

C#版数据结构之--线性表的链式存储(单链表)

1.单链表的定义和由来: 链表是用一组地址可能连续也可能不连续的存储单元来存储线性表中的数据元素,在存储数据元素时,除了要存储数据元素本身之外,还要存储与它相邻的数据元素的地址信息,这两部分组成了线性表中一个数据元素的映像,称之为"结点",存储数据元素本身的部分称之为:数据域,存储相邻数据元素地址的部分称之为:地址域,所有节点通过地址域链接起来,像一个链条,故用此种方式存储的线性表称之为:链表.如果节点的地址域只存储了数据元素的直接后继的存储地址,则称这种链表为:单链表. 与数序表相比

大话数据结构五:线性表的链式存储结构(双向链表)

1. 双向链表:在单链表的每个结点中,再设置一个指向其前驱结点的指针域,那么在双向链表中的结点都有两个指针域,一个指向直接后继,另一个指向直接前驱. 2. 单链表和双向链表比较: 单链表:总是要从头到尾找结点,只能正遍历,不能反遍历. 双向链表: 可以从头找到尾,也可以从尾找到头,即正反遍历都可以,可以有效提高算法的时间性能,但由于每个结点需要记录两份指针,所以在空间占用上略多一点,这就是通过空间来换时间. 3. Java实现双向链表: // 双向链表 public class DoubleLi

大话数据结构四:线性表的链式存储结构(单向循环链表)

1. 单向循环链表:将单链表尾结点的指针端由空指针改为指向头结点,使整个单链表形成一个环,这种头尾相接的单链表称为单向循环链表.   2. 单向循环链表和单链表实现的区别: 1.)添加一个结点到单向循环链表末尾时,必须使其最后一个结点的指针指向表头结点,而不是象单链表那样置为null. 2.)判断是否到达表尾时,单向循环链表可以判断该结点是否指向头结点,单链表只需要知道是否为null.   3.Java实现单向循环链表: // 单向循环链表 public class CircularLinked

大话数据结构三:线性表的链式存储结构(静态链表)

1. 静态链表:用数组描述的链表叫静态链表,通常为方便数据插入,我们会把数组建的大一些. 2. 数组元素(node):由两个数据域组成(data,cursor).数据域data用来存放数据元素,也就是通常我们要处理的数据:而cursor相当于单链表中的指针,存放该元素的后继在数组中的下标. 3. Java实现静态链表: // 静态链表 class StaticLinkedList { private int size; private Node[] node = new Node[100]; /