数据结构 线性表—单链表

本文只要实现单链表的初始化、插入(尾插、头插、任意位置插入)、删除(尾删、头删、删除指定元素)、查找等。

定义单链表

typedef int DataType;
typedef struct LinkNode
{
 DataType data;
 struct LinkNode *next;
}LinkNode, *pLinkNode, *pList;

实现单链表的所有接口:

void InitLinkList(pList* pHead);//单链表的初始化
void Destroy(pList *pHead);//销毁(动态开辟的内存释放)
void PushBack(pList* pHead, DataType x);//尾插
void PopBack(pList* pHead);//尾删
void PushFront(pList* pHead, DataType x);//头插
void PopFront(pList* pHead);//头删
void PrintList(pList list);//打印单链表的元素
int GetListLength(pList head);//获取单链表的长度
pLinkNode Find(pList head, DataType x);//查找元素
void Insert(pList *pHead, pLinkNode pos, DataType x);//任意位置插入元素
void Remove(pList *pHead, DataType x);//删除指定元素
void RemoveAll(pList *pHead, DataType x);//删除单链表中所有指定元素
void Erase(pList *pHead, pLinkNode pos);//按位置删除

实现接口的函数:

void InitLinkList(pList* pHead)//单链表的初始化
{
 assert(pHead);
 *pHead = NULL;
}

void Destroy(pList *pHead)//销毁(动态开辟的内存释放)
{
 assert(pHead);
 pLinkNode del = NULL;
 pLinkNode cur = *pHead;
 while (*pHead)
 {
  del = *pHead;
  *pHead = (*pHead)->next;
  free(del);
  del = NULL;
 }
}

pLinkNode BuyNode(DataType x)//创建新节点
{
 pLinkNode NewNode = (pLinkNode)malloc(sizeof(LinkNode));
 NewNode->data = x;
 NewNode->next = NULL;
 return NewNode;
}

void PushBack(pList* pHead, DataType x)
{
    assert(pHead);
 pLinkNode cur = *pHead;
 pLinkNode NewNode=BuyNode(x);
 if (cur == NULL)
 {
  *pHead = NewNode;
 }
 else
 {
  while (cur->next)
  {
   cur = cur->next;
  }
  cur->next = NewNode;
 }
}

void PrintList(pList list)
{
 pLinkNode cur = list;
 printf("list is: ");
 while (cur)
 {
  printf("%d->", cur->data);
  cur = cur->next;
 }
 printf("over\n");
}

void PopBack(pList* pHead)
{
 assert(pHead);
 pLinkNode cur = *pHead;
 pLinkNode del = NULL;
 if (cur == NULL)
 {
  return;
 }
 else if (cur->next == NULL)
 {
  free(cur);
  *pHead = NULL;
 }
 else
 {
  while (cur->next->next)
  {
   cur = cur->next;
  }
  del = cur->next;
  cur->next = NULL;
  free(del);
  del = NULL;
 }
}

void PushFront(pList* pHead, DataType x)
{
 assert(pHead);
 pLinkNode NewNode = BuyNode(x);
 pLinkNode cur = *pHead;
 if (cur == NULL)
 {
  *pHead = NewNode;
 }
 else
 {
  NewNode->next = *pHead;
  *pHead = NewNode;
 }
}

void PopFront(pList* pHead)
{
 assert(pHead);
 pLinkNode cur = *pHead;
 pLinkNode del = cur;
 if (cur == NULL)
 {
  return;
 }
 else
 {
  *pHead = cur->next;
  free(del);
  del = NULL;
 }
}

int GetListLength(pList head)
{
 
 int count = 0;
 pLinkNode cur = head;
 
 while (cur)
 {
  count++;
  cur = cur->next;
 }
 return count;
}

pLinkNode Find(pList head, DataType x)
{
 pLinkNode cur = head;
 
 while (cur)
 {
  if (cur->data == x)
   return cur;
  else
   cur = cur->next;
 }
 return NULL;
}

void Insert(pList *pHead, pLinkNode pos, DataType x)
{
 assert(pHead);
 assert(pos);
 pLinkNode cur = *pHead;
 pLinkNode NewNode = BuyNode(x);
 if (cur ==pos)
 {
  NewNode->next = cur;
  *pHead = NewNode;
 }
 else
 {
  while (cur->next!=pos)
  {
   cur = cur->next;
  }
  NewNode->next =cur->next;
  cur->next = NewNode;
 }
}

void Remove(pList *pHead, DataType x)
{
 assert(pHead);
 pLinkNode cur = *pHead;
 pLinkNode prev = NULL;
 pLinkNode del = NULL;
 while (cur)
 {
  if (cur->data == x)
  { 
   del = cur;
   if (cur == *pHead)
   {
    *pHead = cur->next;
   }
   else
   {
    prev->next = cur->next;
   }
   free(del);
   del = NULL;
   break;
  }
  prev = cur;
  cur = cur->next;
 }
}

void Erase(pList *pHead, pLinkNode pos)
{
 assert(pHead);
 assert(pos);
 pLinkNode cur = *pHead;
 pLinkNode del = cur;
 pLinkNode prev = NULL;
 while (cur)
 {
  del = cur;
  if (cur == pos)
  {
   if (cur == *pHead)
   {
    *pHead = cur->next;
   }
   else
   {
    prev->next = cur->next;
   }
   free(del);
   del = NULL;
   break;
  }
  prev = cur;
  cur = cur->next;
 }
}

void RemoveAll(pList *pHead, DataType x)
{
 assert(pHead);
 pLinkNode cur = *pHead;
 pLinkNode prev = NULL;
 pLinkNode del = NULL;
 while (cur)
 {
  if (cur->data == x)
  {
   del = cur;
   if (cur == *pHead)
   {
    *pHead = cur->next;
    cur = *pHead;
   }
   else
   {
    prev->next = cur->next;
    cur = prev->next;
   }
   free(del);
   del = NULL;
  }
  else
  {
   prev = cur;
   cur = cur->next;
  }
 }
}
时间: 2024-11-05 06:14:30

数据结构 线性表—单链表的相关文章

[考研系列之数据结构]线性表之链表

1.链表分类 通过线性表概述,我们知道了链表这样一种数据结构,它又分成三类,分别是 单向链表 循环链表 双向链表 单向链表 单向链表的指针域只有一个指向下一个节点的指针,需要注意几点: 1.头指针--指向第一个节点 2.最后一个结点的指针指向NULL 3.头结点--在链表的第一个结点之前附设一个结点,它的数据域为空 所以,我们看到:  单向链表为空的<=>链表有且只有一个头结点<=>头结点的指针指向NULL 循环链表 循环链表和单向链表最大的不同就是:最后一个结点的指针不再指向NU

C语言 严蔚敏数据结构 线性表之链表实现

博主最近在考成都大学皇家计算机科学与技术专业,复习专业课数据结构,正好学习到线性结构中的线性表用链表这种存储结构来实现. 首先,数据结构包括1.数据的操作2.逻辑结构3.存储结构(数据结构三要素. 直接上代码,现阶段代码实现功能有:链表初始化.遍历.增.删.返回链表长度,后续功能陆续发布.其中肯定有很多问题,希望各位码哥留言. Linklist* InitList(int i)//i为链表大小 { Linklist *head; head = (Linklist*)malloc(sizeof(L

数据结构之 线性表---单链表的拆分

数据结构实验之链表五:单链表的拆分 Time Limit: 1000MS Memory limit: 65536K 题目描述 输入N个整数顺序建立一个单链表,将该单链表拆分成两个子链表,第一个子链表存放了所有的偶数,第二个子链表存放了所有的奇数.两个子链表中数据的相对次序与原链表一致. 输入 第一行输入整数N;: 第二行依次输入N个整数. 输出 第一行分别输出偶数链表与奇数链表的元素个数: 第二行依次输出偶数子链表的所有数据: 第三行依次输出奇数子链表的所有数据. 示例输入 10 1 3 22

数据结构之 线性表---单链表操作A (删除链表中的指定元素)

数据结构上机测试2-1:单链表操作A Time Limit: 1000MS Memory limit: 4096K 题目描述 输入n个整数,先按照数据输入的顺序建立一个带头结点的单链表,再输入一个数据m,将单链表中的值为m的结点全部删除.分别输出建立的初始单链表和完成删除后的单链表. 输入 第一行输入数据个数n: 第二行依次输入n个整数: 第三行输入欲删除数据m. 输出 第一行输出原始单链表的长度: 第二行依次输出原始单链表的数据: 第三行输出完成删除后的单链表长度: 第四行依次输出完成删除后的

数据结构之 线性表---单链表的操作B(先逆序+再删除重复元素)

数据结构上机测试2-2:单链表操作B Time Limit: 1000MS Memory limit: 65536K 题目描述 按照数据输入的相反顺序(逆位序)建立一个单链表,并将单链表中重复的元素删除(值相同的元素只保留最后输入的一个). 输入 第一行输入元素个数n: 第二行输入n个整数. 输出 第一行输出初始链表元素个数: 第二行输出按照逆位序所建立的初始链表: 第三行输出删除重复元素后的单链表元素个数: 第四行输出删除重复元素后的单链表. 示例输入 10 21 30 14 55 32 63

【 数据结构(C语言)】线性表——单链表

1.线性链表:用任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的也可以是不连续) #include <bits/stdc++.h> using namespace std; #define ElemType int #define Status int #define ERROR -1 #define OK 1 typedef struct LNode { ElemType data; struct LNode *next; }LNode ,*LinkList; LinkList

数据结构(一)线性表单链表试题

题目 快速找到未知长度的单链表的中间节点 解决思路 (一)使用一个指针,先索引一遍获取总长度,再取长度一半去循环获取到中间值 算法复杂度:O(L)+O(L/2) = O(3L/2) (二)使用两个指针,快指针和慢指针,快指针一次向前走2格,慢指针一次走一格,当快指针走完全程,慢指针正好走在中间 算法复杂度:O(L/2) 方法二:代码实现 //快速查找中间元素 int FindMidEle(LinkList L, Elemtype *e) { LinkList search, middle; //

再回首,数据结构——线性表、链表上的常见算法

最近在复习数据结构,顺便看看大一的时候写的代码,看完之后比当初有了更加深刻的体会. 希望这些能提供给初学者一些参考. //1.编写算法实现线性表就地逆置的操作 void InverseList (SeqList l) { for (i = 0; i <= (l.length-1)/2; i++) { l.elem[i] <-> l.elem[l.length-1-i]; } } //2.从顺序表中删除自第i个元素开始的k个元素 void DeleteList(SeqList l, int

JAVA实现具有迭代器的线性表(单链表)

一,迭代器的基本知识: 1,为什么要用迭代器?(迭代:即对每一个元素进行一次“问候”) 比如说,我们定义了一个ADT(抽象数据类型),作为ADT的一种实现,如单链表.而单链表的基本操作中,大部分需要用到依次遍历单链表中的每一个元素.一般而言,我们就是用for循环来实现遍历,这样,当你新增一个对单链表的操作并需要使用遍历时,你就得重新写一个for循环而实现遍历.那么,为什么不将迭代(遍历)作为一种基本的ADT操作(基本的ADT操作如:新增一个元素.删除一个元素)呢?于是,迭代器就出场了. 2,鉴于