list 线性链表的相关操作。

线性链表的操作比较简单,只需要在内存的堆中进行动态申请空间分配给相应的变量即可。另外,需要一个头指针来保存住这样链表的首地址,这样的话可以在对已经创建好的线性链表进行操作时,能够找到。如果没有头结点,那就跟内存泄露差不多,你都再内存中找不到,虽然是创建了一个链表,但是没法用。就好像一个人有很多的money,但是,money忘记放在家里那个位置了,可能已经没了呢。所以,说必须能够找的到,才能用地着。

由于线性表的操作中存在一定的缺陷,不如说必须从头开始遍历整个表才能找到你想要的元素,这样的话,必定会增加了时间复杂度。但是,如果是在表中进行插入和删除时,则不会存在这样的问题。

相关的操作和一些代码:

可以把一些常用的操作写到一个头文件中,这样的话,你可以在。cpp文件中进行操作的扩展,比如要检验一个线性表中的元素是否存在是,那些表的创建等操作就可以直接调用。但是写成类,则更好了。

// list-operat.h

#ifndef _LIST_OPERTAT_H
#define _LIST_OPERTAT_H


typedef struct Node
{
 Node* next;
 int iData;
}LNode,*LinkList;

// 创建一个节点数为n的线性链表;
LinkList Creat(int n)
{
 LinkList r, p = NULL;
 LinkList head = NULL;
 int num = 0;
 for (int i = 0;i < n;++ i)
 {
  cin >> num;
  p = (LinkList)malloc(sizeof(LNode));
  p->iData = num;
  p->next = NULL;
  if (head == NULL)
  {
   head = p;
  }
  else
  {
   r->next = p;
  } 
  r = p;
 }
 return head;
}

int Length(LinkList& Lis)
{
 if (Lis == NULL)
 {
  cout << "该线性链表为空" << endl;
  return -1;
 }
 LinkList p = Lis;
 int iSum = 0;
 while (p != NULL)
 {
  p = p->next;
  iSum ++;
 }
 return iSum;
}

// 递归算法来算一个线性链表的长度;
int Length2(LinkList& Lis)
{
 if (Lis != NULL)
 {
  return 1 + Length2(Lis->next);
 }
 else
  return 0;
}

// 测试线性表是否为空;
int IsEmpty(LinkList& List)
{
 return List == NULL;
}

// 确定元素item在线性表中的位置;
LinkList Locate(LinkList& list,int item)
{
 if (list != NULL)
 {
  LinkList p = list;
  while(p!=NULL && p->iData != item)
  {
   p = p->next;
  }
  return p;
 }
}
 
// 在线性非空链表的第一个位置插入一个链接点;
void InsertHead(LinkList& list,int item)
{
 if (list != NULL)
 {
  LinkList p = NULL;
  p = (LinkList)malloc(sizeof(LNode));
  p->iData = item;
  p->next = list;
  list = p;
 }
}

// 在非空线性链表的末尾插入一个元素为item的链接点;
void InsertTail(LinkList& list,int item)
{
 if (list != NULL)
 {
  LinkList r,p = NULL;
  p = (LinkList)malloc(sizeof(LNode));
  p->iData = item;
  r = list;
  while(r != NULL)
  {
   r = r->next;
  }
  p->next = NULL;
  r->next = p;
 }
}

// 在线性表中由一个确定指针指出的链接点后面插入一个数据信息为item的链接点;
void InsertFireList(LinkList& list,LinkList q,int item)
{
 if (list != NULL)
 {
  LinkList p,r;
  p = (LinkList)malloc(sizeof(LNode));
  p->iData = item;
  q->next = p->next;
 }
}

// 在线性表的第i个链接点后面插入一个数据信息为item的链接点;
void InsertFireLocat(LinkList& list,int i,int item)
{
 if (list != NULL)
 {
  LinkList p,q = list;
  int iTemp = 1;
  while(iTemp < i && q->next != NULL)
  {
   q = q->next;
   iTemp ++;
  }
  if(iTemp != i || q == NULL)
  {
   cout << "您输入的第i个位置不存在!" << endl;
  }
  else
  {
   p = (LinkList)malloc(sizeof(LNode));
   p->iData = item;
   p->next = q->next;
   q->next = p;
  }
 }
}

// 该题分成两种情况(表是按从小到大的顺序排列的);
// 1.插入的item元素小于第一个元素,直接插入在第一个元素的前面;
// 2.插入的item元素正好在线性链表的中间;
// 在按值有序链接的线性链表中插入一个数据信息为item的链接点;
void InsertSortList(LinkList& list,int item)
{
 LinkList p,q,r;
 p = (LinkList)malloc(sizeof(LNode));
 if (list == NULL || item < list->iData)
 {
  p->iData = item;
  p->next = list;
  list = p;
 }
 else
 {
  q = list;
  while(q != NULL && item > q->iData)
  {
   r = q;
   q = q->next;
  }
  p->next = q;
  r->next = p;       // 将新的链接点插入在q指示的链接点后面;
 }
}

// 从非空的线性链表中删除q所指的链接点;
void DeleteList(LinkList& list,LinkList& q)
{

 LinkList r = NULL;
 if (q == list)
 {
  list = q->next;
  free(q);
 }
 else
 {
  r = list;
  while(r->next != q && r->next != NULL)
  {
   r = r->next;
  }
  if(r->next != NULL)
  {
   r->next = q->next;
   free(q);
  }
 }
}

// 销毁一个线性链表;
void DestroyList(LinkList& list)
{
 if (list != NULL)
 {
  LinkList p = list;
  while(p != NULL)
  {
   list = p->next;
   free(p);
   p = list;
  }
 }
}


// 删除线性链表中数据域值为item的所有链接点;
// 删除的位置不同处理的结果不相同。如果处理的位置在第一个位置,则需要和在第二个位置之后的区分;
void DeleteItem(LinkList& list,int item)
{
 if (list != NULL)
 {
  LinkList p,q = list;
  
  // 从第二个链接点开始遍历,满足条件进行如下的操作;
  p = list->next;
  while(p != NULL)
  {
   if (p->iData == item)
   {
    q->next = p->next;
    free(p);
    p = q->next;
   }
   else
   {
    q = p;
    p = p->next;
   }
  }

  ///
  // 若第一个节点满足条件则进行如下的操作;
  if (list->iData == item)
  {
   q = list;
   list = list->next;
   free(q);
  }
 }
}

// 逆转一个线性链表;
// 此算法十分的精妙;
void Invert(LinkList& list)
{
 if (list != NULL)
 {
  LinkList p,q,r;
  p = list;
  q = NULL;
  while (p != NULL)
  {
   r = q;
   q = p;
   p = p->next;
   q->next = r;
  }
  list = q;  // 链表逆转结束;
 }
}

// 将两个非空线性连接成一个线性链表;
void Connect(LinkList& lista,LinkList& listb)
{
 LinkList p = lista;
 while(p != NULL)
 {
  p = p->next;
 }
 p->next = listb;
}

// 将两个非空的线性表按照值有序合并为一个按值有序链接的线性链表;
LinkList MergeList(LinkList& lista,LinkList& listb)
{
 LinkList listc,p = lista,q = listb,r;
 if (lista->iData <= listb->iData)
 {
  listc = lista;
  r = lista;
  p = lista->next;
 }
 else
 {
  listc = listb;
  r = listb;
  q = listb->next;
 }
 while(p!= NULL && q != NULL)
 {
  if (p->iData <= q->iData)
  {
   r->next = p;
   r = p;
   p = p->next;
  }
  else
  {
   r->next = q;
   r = q;
   q = q->next;
  }
 }
 r->next = p ? p: q;          // 插入剩余链接点;
 return listc;               // 返回合并后的链表第一个链接点地址;
}

 

// 复制一个线性链表;分成两种情况:1、线性链表为空;2.线性链表不为空;
LinkList Copy(LinkList& lista)
{
 LinkList listb = NULL;
 if (lista == NULL)
 {
  return NULL;
 }
 else
 {
  listb = (LinkList)malloc(sizeof(LNode));
  listb->iData = lista->iData;
  listb->next = Copy(lista->next);
 }
 return listb;
}

// 利用线性链表进行数据排序;
void Select(int a[],int n)
{
 LinkList p,list = NULL;
 for (int i = 0;i < n;++ i)
 {
  InsertSortList(list,a[i]);
 }
 p = list;
 i = 0;
 while(p != NULL)
 {
  a[i ++] = p->iData;
  p = p->next;
 }
}
#endif

 

// main函数,自己定义吧。。

单链表如果用c++ 实现的话,则必须能够对模板的使用要熟悉一些。我那块掌握的还不是太好,需要多多看书。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值