链表的简单操作(插入,删除,置反,输出,合并,去重)

链表的核心就是指针,初接触可能不太熟悉。不会用就多用,熟能生巧


定义一个结构体类型,其中由数据类型和指针构成。有指针就相当于知道了门牌号,可以依次知道下个元素

typedef struct node{
int data;
struct node *next;
}Node,*LinkList;

链表的初始化,分配内存,判断是否有内存,头结点为空勿忘

LinkList initailList(void) //链表的初始化
{
  LinkList list;

  list = (LinkList)malloc(sizeof(Node));
  if (!list)
    printf("无可分配内存\n");
  else
  {
    list->next = NULL; //头结点为空勿忘
    printf("初始化成功\n");
    return list;
  }
}

尾插法创建链表。将数据不断插到尾部,例如:1,5,7,9,11. 输出为:11,9,7,5,1.故想正序输出需要置反



链表节点的插入,判断插入位置是否合法。例如只有五个元素,插入到第8个元素,即为不合法


void insertList(LinkList list, int place, int x)
{
  LinkList p = list;
  LinkList new_node;
  int i = 0;

  if (place > n || place < 0)
    printf("位置不合法\n");

  while(p && i++ < place-1)
  {
    p = p->next;
  }

  new_node = (LinkList)malloc(sizeof(Node));


  new_node->next = p->next;
  p->next = new_node;

  new_node->data = x;
}


链表指定位置的删除。首先位置判断是否合法。然后后节点覆盖前节点


void deleteList(LinkList list, int place)
{
  LinkList p = list, q;
  int i = 0;
  if (place < 0 || place > n)
    printf("删除位置不合法\n");

  while(p && i++ < place - 1)
  {
    p = p->next;
  }

  q = p->next;
  p->next = q->next;

  free(q);
}

链表的去重。保留上一节点,然后向后进行遍历,遇到重复单元进行删除即可


void deleteValue(LinkList list)
{
  LinkList p, q, r;
  p = list->next;

  while(p)
  {
    r = p;    //保留上一个节点

    while(r->next)
    {
      if (r->next->data == p->data)
      {
        q = r->next;    //下一个节点
        r->next = q->next;    //下下个节点覆盖掉上一个
        free(q);
      }
      else
        r = r->next;    //遍历后续节点
    }

    p = p->next;
  }
}

链表的置反。


void reverseList(LinkList list)
{
  LinkList q, p;

  if (!list)
    printf("无元素\n");

  p = list->next;

  while(p->next)
  {
    q = p->next;
    p->next = q->next;
    q->next = list->next;
    list->next = q;
  }
}

链表的交叉合并,创建一个新表,将两个进行插入

LinkList combineList(LinkList x, LinkList y)
{
  LinkList list = (LinkList)malloc(sizeof(Node));

  LinkList p = list, px = x->next, py = y->next;

  while(px||py) //归并
  {
    if (px)
    {
      p->next = (LinkList)malloc(sizeof(Node));
      p = p->next;
      p->data = px->data;
      px = px->next;
    }

    if (py)
    {
      p->next = (LinkList)malloc(sizeof(Node));
      p = p->next;
      p->data = py->data;
      py = py->next;
    }
  }

  p->next = NULL;
  return list;

}

链表输出,非空输出即可


void print(LinkList list)
{
  LinkList p = list->next;
  while(p)
  {
    printf("%d  ", p->data);
    p = p->next;
  }
  putchar('\n');
}

完整的程序及测试代码如下

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

typedef struct node{
int data;
struct node *next;
}Node,*LinkList;

int n, m;

LinkList initailList(void) //链表的初始化
{
  LinkList list;

  list = (LinkList)malloc(sizeof(Node));
  if (!list)
    printf("无可分配内存\n");
  else
  {
    list->next = NULL; //头结点为空勿忘
    printf("初始化成功\n");
    return list;
  }
}

void createList(LinkList list, int num) //尾插法创建链表
{
  printf("请输入值:");
  for(int i = 0; i < num; i++)
  {
    LinkList p;
    p = (LinkList)malloc(sizeof(Node));
    if (!p)
      printf("无可分配的内存\n");

    scanf("%d", &p->data);
    p->next = list->next;
    list->next = p;
  }
}

void insertList(LinkList list, int place, int x)
{
  LinkList p = list;
  LinkList new_node;
  int i = 0;

  if (place > n || place < 0)
    printf("位置不合法\n");

  while(p && i++ < place-1)
  {
    p = p->next;
  }

  new_node = (LinkList)malloc(sizeof(Node));


  new_node->next = p->next;
  p->next = new_node;

  new_node->data = x;
}



void deleteValue(LinkList list)
{
  LinkList p, q, r;
  p = list->next;

  while(p)
  {
    r = p;    //保留上一个节点

    while(r->next)
    {
      if (r->next->data == p->data)
      {
        q = r->next;    //下一个节点
        r->next = q->next;    //下下个节点覆盖掉上一个
        free(q);
      }
      else
        r = r->next;    //遍历后续节点
    }

    p = p->next;
  }
}

void deleteList(LinkList list, int place)
{
  LinkList p = list, q;
  int i = 0;
  if (place < 0 || place > n)
    printf("删除位置不合法\n");

  while(p && i++ < place - 1)
  {
    p = p->next;
  }

  q = p->next;
  p->next = q->next;

  free(q);
}

LinkList combineList(LinkList x, LinkList y)
{
  LinkList list = (LinkList)malloc(sizeof(Node));

  LinkList p = list, px = x->next, py = y->next;

  while(px||py)
  {
    if (px)
    {
      p->next = (LinkList)malloc(sizeof(Node));
      p = p->next;
      p->data = px->data;
      px = px->next;
    }

    if (py)
    {
      p->next = (LinkList)malloc(sizeof(Node));
      p = p->next;
      p->data = py->data;
      py = py->next;
    }
  }

  p->next = NULL;
  return list;

}

void reverseList(LinkList list)
{
  LinkList q, p;

  if (!list)
    printf("无元素\n");

  p = list->next;

  while(p->next)
  {
    q = p->next;
    p->next = q->next;
    q->next = list->next;
    list->next = q;
  }
}



void print(LinkList list)
{
  LinkList p = list->next;
  while(p)
  {
    printf("%d  ", p->data);
    p = p->next;
  }
  putchar('\n');
}


int main(void)
{
  LinkList list, otherlist;
  int flag, place, num;

  list = initailList();
  printf("请输入数据个数:");
  scanf("%d", &n);
  createList(list, n);
  reverseList(list);

  printf("1.查看链表        2.插入元素    3.删除位置\n");
  printf("4.置反        5.删除元素    6.合并链表      7.退出\n");
  while(scanf("%d", &flag) && flag != 7)
  {
    switch(flag)
    {
      case 1: print(list); break;
      case 2: printf("请输入要插入的位置和值:");scanf("%d %d", &place, &num);insertList(list, place, num);print(list);  break;
      case 3: printf("请输入要删除的位置:");scanf("%d", &num); deleteList(list, num);print(list);  break;
      case 4: printf("置反后\n\n");reverseList(list);print(list);break;
      case 5: printf("输入删除的元素\n");deleteValue(list); print(list); break;
      case 6: printf("创建另一个链表\n");otherlist = initailList();printf("请输入数据个数:");scanf("%d", &m);createList(otherlist, m);
              reverseList(otherlist);list = combineList(list, otherlist);print(list);break;
      default: printf("操作不合法\n");break;
    }
  }

  return 0;
}




  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值