期末复习 单链表的基本运算(数据结构——C语言实现)

单链表的存储结构描述如下

typedef struct Node 
{
ElemType data;
struct Node* next;
}Node,*LIninkList;

LinkList和Node同为结构指针类型,这两种类型等价。通常习惯上用LinkList说明指针变量,如,使用LinkList L,则L为单链表头指针,从而提高程序可读性。用Node来定义指向单链表中结点的指针,如Node *p,则p为指向单链表中结点的指针变量。

1.初始化单链表

InitList(LinkList *L)
{
*L=(LinkList)malloc(sizeof(Node));//建立头结点
(*L)->next=NULL;//建立空的单链表L
}

注意:L是指向单链表的头结点的指针,用来接收主程序中待初始化单链表的头指针变量的地址,*L相当于主程序中待初始化单链表的头指针变量。

2.建立单链表
(1).头插法
得到的链表逻辑顺序与输入元素顺序相反

void CreatFromHead(LinkList L)
{
//L是带头结点的空链表头指针
Node *s;
char c;
int flag=1;
while(flag)//输入‘$’时,flag=0,结束
{
c=getchar();
if(c!='$')
{
  s=(Node*)malloc(sizeof(Node));
  s->data=c;
  s->next=L->next;   //s指向L指的位置
  L->next=s;         //L指向s,顺序不能乱,乱了就找不到数据了
}
else flag=0;
}
}

(2).尾插法
将新结点插入到当前单链表的表尾,为此需要增加一个尾指针r,使之指向单链表表尾(方便指向插入的结点)

 void CreatFromTail(LinkList L)
 {
 Node *r,*s;
 int flag=1;
 r=L;//r初值指向头结点
 while(flag)
 {
   c=getchar();
   if(c!='$')
   {
     s=(Node *)malloc(sizeof(Node));
     s->data=c;
     r->next=s;
     r=s;
   }
   else
   {
     flag=0;
     r->next=NULL;
   }
 }
 }

3.查找
(1).按序号查找
要查找带头结点的单链表中的第i个元素,需要从头扫描,可设置j为计数器,当j=i时,指针p指向的结点就是要找的第i个结点。

  Node* Get(LinkList L,int i)
  {
  int j;
  Node *p;
  if(i<=0)
  return NULL;
  p=L;
  j=0;
  while((p->next!=NULL)&&(j<i))
  {
    p=p->next;
    j++;
  }
  if(i==j)
  return p;
  else 
  return NULL;
  }

(2).按值查找

Node* Locate(LinkList L,ElemType key)
{
  Node *p;
  p=L->next;
  while(p!=NULL)
  if(p->data!=key)
  p=p->next;
  else
  break;
  return p;
}

4.求单链表长度

int ListLength(LinkList L)
{
  Node *p;
  p=L->next;
  j=0;
  while(p!=NULL)
  {
    p=p->next;
    j++;
  }
  return j;
}

5.单链表插入操作

1.查找(找位置):在单链表中找到第i-1个结点并由指针pre指示。
2.申请:申请新结点s,并将其数据域的值设为e;
3.插入挂链:通过修改指针域将新结点s挂入单链表L。

void InsList(LinkList L,int i,ElemType e)
{
  Node *p,*s;
  int k;
  if(i<=0)
  return ERROR;
  pre=L;
  k=0;
  while(pre!=NULL&&k<i-1)
  {
    pre=pre->next;
    k=k+1       //将pre指向第i-1个结点;
  }
  if(pre==NULL)
  {
    printf("插入位置不合理");
    return ERROR;
  }
  s=(Node*)malloc(sizeof(Node));
  s->data=e;
  s->next=pre->next;      //指针s指向pre指向的位置
  pre->next=s;            //pre指向s
  return OK;
}

6.单链表的删除操作
1.查找:通过计数方法找到第i-1个结点并由指针pre表示。
2.删除第i个结点并释放空间。

int DelList(LinkList L,int i;ElemType *e)
{
  Node *pre,*r;
  int k;
  pre=L;k=0;
  while(pre->next!=NULL&&k<i-1)//查找第i-1个结点
  {
    pre=pre->next;
    k=k+1;
  }
  if(pre->next==NULL)
  {
    printf("删除结点位置不合理");
    return ERROR;
  }
  r=pre->next;  //r指向第i个结点
  pre->next=r->next;//pre指向第i+1个结点
  *e=r->data;
  free(r);//释放结点空间
  return OK;
}

7.合并两个有序单链表

LinkList MregeLinkList(LinkList LA,LinkList LB)
{
  Node *pa,*pb;
  LinkList LC;//将LC初始置空表,pa和pb分别指向单链表LA,LB中第一个结点,r初值LC
                    //并且r始终指向LC表尾
  pa=LA->next;
  pb=LB->next;
  LC=LA;//用LA头结点作为LC头结点
  LC->next=NULL;
 r=LC;
 while(pa!=NULL&&pb!=NULL)
 {
   if(pa->data<=pb->data)
   {
      r->next=pa;//r指向pa
      r=pa;//r移动至pa;
      pa=pa->next;//pa移动至下一结点
   }
   else
   {
      r->next=pb;
      r=pb;
      pb=pb->next;
   }
   }
   if(pa)//若LA未完,将LA中后续元素链到新表LC中
   r->next=pa;
   else
   r->next=pb;
   free(LB);
   return LC;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值