C语言数据结构 link 链表反转的实现

C语言数据结构 link 链表反转的实现

链表反转,示例如下:

偶数个输入:a->b->c->d->e->f
偶数个输出:e->f->c->d->a->b
or
奇数个输入:a->b->c->d->e->f->g
偶数个输出:g->e->f->c->d->a->b

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

/************** start of stack *************/ 

#define STACK_SIZE 1024 

char stack[STACK_SIZE];
int top = 0; 

void push(char ch){
  stack[top] = ch;
  top++;
} 

char pop(){
  top--;
  return stack[top];
} 

int isempty(){
  return 0 == top;
} 

void test_stack(){
  push('a');
  push('b');
  push('c');
  push('d'); 

  while(!isempty()){
    printf("pop ch: %c\n", pop());
  }
} 

/************** end of stack *************/ 

struct _node{
  char data;
  struct _node *next;
}; 

typedef struct _node node, *plink; 

plink init_link(){
  plink pl;
  pl = (plink)malloc(sizeof(node)); 

  // check malloc success or not
  if(NULL == pl) {
    printf("malloc memory fail...");
    return NULL;
  } 

  // init link head
  pl->data = '\0';
  pl->next = NULL; 

  return pl;
} 

void input_data(plink pl, char data){
  plink p = pl; 

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

  plink node = NULL;
  node = (plink)malloc(sizeof(node));   // malloc a new node 

  // add data
  if(NULL != node){
    node->data = data;
    node->next = p->next;    // last next is NULL
    p->next = node;
    p = node;          // p point last node
  }
} 

void output_link(plink pl){
  if(NULL == pl){
    printf("plink is null");
    return;
  } 

  plink p = pl->next;  // already check pl is NULL, so here is ok
  while(NULL != p){
    printf("%c -> ", p->data);
    p = p->next;
  }
  printf("\n\n");
} 

// push and pop stack
plink revert_link2(plink pl){
  plink p = pl; 

  while(p->next){
//    printf("p->data: %c\n", p->next->data);
    if(p->next->next){
      push(p->next->next->data);
      push(p->next->data);
      p = p->next->next;
    } else {
      push(p->next->data);
      p = p->next;
    }
  } 

  while(!isempty()){
    printf("%c -> ", pop());
  } 

  printf("\n\n"); 

  return NULL;
} 

plink revert_link(plink pl){
  if(NULL == pl){  // check link is NULL
    return NULL;
  } 

  int link_len = 0;
  plink tmp_pl = pl->next; 

  while(tmp_pl){  // count link count
    link_len++;
    tmp_pl = tmp_pl->next;
  } 

  // link length is no more than two node(s)
  if(link_len <= 2){
    return pl;
  } 

  // link length is more than two nodes
  return revert_link2(pl);
} 

int main(){
  plink pl = NULL; 

  pl = init_link();     // init link head 

  input_data(pl, 'a');   // add data
  input_data(pl, 'b');
  input_data(pl, 'c');
  input_data(pl, 'd');
  input_data(pl, 'e');
  input_data(pl, 'f');
  input_data(pl, 'g'); 

  output_link(pl); 

  plink pl2 = revert_link(pl); 

  output_link(pl2); 

  return 0;
} 

/****
revert_link.c 

linux gcc compile
gcc revert_link.c -o revert_link && ./revert_link 

output result: 

a -> b -> c -> d -> e -> f -> g
g -> e -> f -> c -> d -> a -> b 

or 

a -> b -> c -> d -> e -> f
e -> f -> c -> d -> a -> b 

****/

间隔螺旋反转:

输入: a -> b -> c -> d -> e -> f
输出: b -> a -> d -> c -> f -> e

plink revert_link3(plink pl){
  if(NULL == pl){
    printf("plink is null");
    return NULL;
  }   

  plink p = pl;
  plink first = p->next;
  while(NULL != first){
    plink second = first->next;
    if(NULL != second){
      first->next = second->next;   // third node
      second->next = first;      // revert two nodes
      first = first->next;
      p->next = second;
      p = second->next;
    }
  }
  return pl;
}

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • 用C++类实现单向链表的增删查和反转操作方法

    数据结构这东西,理解起来不算难,但是实现难度就不小了,虽然思路很清晰,但不知道从何下手还有语言的细节问题一直是阻碍初学者的主要障碍(比如我).今天用了一下午时间终于独立完成了链表操作. 找网上的代码,大多用了结构体,还有些并不适合刚学c++或者数据结构的人看,于是我是用类写的,代码比较符合学生的习惯和水平. 先看类定义 class node { public: int data; node *next; }; class linklist { node *h; --//一些函数 } 两个类,no

  • 如何使用递归和非递归方式反转单向链表

    问题:给一个单向链表,把它从头到尾反转过来.比如: a -> b -> c ->d 反过来就是 d -> c -> b -> a . 分析:假设每一个node的结构是: 复制代码 代码如下: class Node { char value; Node next;} 因为在对链表进行反转的时候,需要更新每一个node的"next"值,但是,在更新 next 的值前,我们需要保存 next 的值,否则我们无法继续.所以,我们需要两个指针分别指向前一个节点

  • C++数据结构与算法之反转链表的方法详解

    本文实例讲述了C++数据结构与算法之反转链表的方法.分享给大家供大家参考,具体如下: 算法概述:要求实现将一条单向链表反转并考虑时间复杂度. 算法分析: 数组法(略): 将列表元素逐个保存进数组,之后再逆向重建列表 点评:实现逻辑最简单,需要额外的内存开销. 移动指针: 通过三个指针逐个从链表头开始逐一反转链表元素的指针 点评:不需要额外的内存开销,会改变原始链表. 递归: 以递归的方式首先找到链表尾部,再逐一反转指针 点评:不需要额外的内存开销,不会改变原始链表. 算法实现: 构建链表结构 /

  • C语言数据结构 link 链表反转的实现

    C语言数据结构 link 链表反转的实现 链表反转,示例如下: 偶数个输入:a->b->c->d->e->f 偶数个输出:e->f->c->d->a->b or 奇数个输入:a->b->c->d->e->f->g 偶数个输出:g->e->f->c->d->a->b #include <stdio.h> #include <malloc.h> #incl

  • C语言数据结构实现链表逆序并输出

    C语言数据结构实现链表逆序并输出 将一个链表逆序并输出.我用了两种方法来实现,第一种是借助了一个新的空链表:第二种是在原来链表的基础上直接实现逆序. 实例代码: 头文件: #include <stdio.h> #include <stdlib.h> #include <malloc.h> typedef int ElemType; typedef struct Node {//结点结构 ElemType value; //值域 struct Node *next;//指

  • C语言数据结构旋转链表的实现

    C语言数据结构旋转链表的实现 实例: 给出链表1->2->3->4->5->null和k=2 返回4->5->1->2->3->null 分析: 感觉很直观,直接把分割点找出来就行,记得k可能大于len,要取模 代码: /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x

  • C语言数据结构实现链表去重的实例

    C语言数据结构实现链表去重的实例 题目及分析 链表去重 时间限制 300 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 给定一个带整数键值的单链表L,本题要求你编写程序,删除那些键值的绝对值有重复的结点.即对任意键值K,只有键值或其绝对值等于K的第一个结点可以被保留.同时,所有被删除的结点必须被保存在另外一个链表中.例如:另L为21→-15→-15→-7→15,则你必须输出去重后的链表21→-15→-7.以及被删除的链表-15→15. 输入格式: 输入

  • C语言实现单链表反转

    一.理解指针 看懂链表的结构并不是很难,但是一旦把它和指针混在一起,就很容易让人摸不着头脑.所以,要想写对链表代码,首先就要理解好指针. 有些语言有"指针"的概念,比如 C 语言:有些语言没有指针,取而代之的是"引用",比如 Java.Python.不管是"指针"还是"引用",实际上,它们的意思都是一样的,都是存储所指对象的内存地址. 将某个变量赋值给指针,实际上就是将这个变量的地址赋值给指针,或者反过来说,指针中存储了这个变

  • C语言数据结构单链表接口函数全面讲解教程

    目录 前言 一.链表的概念及结构 1.概念 二.链表的使用 1.遍历整个链表 2.尾插 3.头插 4.头删 5.尾删 6.任意位置插入数据 7.任意位置删除数据 后记 前言 上一期数据结构专栏我们学习了顺序表后:C语言数据结构顺序表 在运用时,细心的同学可能会发现,如果要头插.尾插或者任意位置.如果原先的空间已经被占满了,你是需要扩容的,动态链表扩容往往是2倍,但是扩容后,如果后面没有使用完全扩容后空间就会造成空间浪费,为了解决这个问题,我们今天将学习链表. 提示:以下是本篇文章正文内容,下面案

  • C语言 数据结构链表的实例(十九种操作)

    C语言 数据结构链表的实例(十九种操作) #include <stdio.h> #include <string.h> #include <stdlib.h> /*************************************************************************************/ /* 第一版博主 原文地址 http://www.cnblogs.com/renyuan/archive/2013/05/21/30915

  • C语言数据结构之单链表存储详解

    目录 1.定义一个链表结点 2.初始化单链表 3.输出链表数据 4.完整代码 如果说,顺序表的所占用的内存空间是连续的,那么链表则是随机分配的不连续的,那么为了使随机分散的内存空间串联在一起形成一种前后相连的关系,指针则起到了关键性作用. 单链表的基本结构: 头指针:永远指向链表第一个节点的位置. 头结点:不存任何数据的空节点,通常作为链表的第一个节点.对于链表来说,头节点不是必须的,它的作用只是为了方便解决某些实际问题. 首元结点:首个带有元素的结点. 其他结点:链表中其他的节点. 1.定义一

  • C语言数据结构之单链表操作详解

    目录 1.插入操作 2.删除操作 3.查找操作 4.修改操作 5.完整代码 1.插入操作 (1)创建一个新的要插入的结点 (2)将新结点的 next 指针指向插入位置后的结点 (3)将插入位置前的节点指针 next 指向新的结点 注意:步骤(2)(3)的顺序不能颠倒,否则会导致插入位置后的部分链表丢失. 插入位置一共分三种,分别是头部插入.中间插入和尾部插入. 如图: 代码: link* insertElem(link* p,int elem,int pos){ link* temp = p;/

  • Go语言数据结构之单链表的实例详解

    目录 任意类型的数据域 实例01 快慢指针 实例02 反转链表 实例03 实例04 交换节点 实例05 任意类型的数据域 之前的链表定义数据域都是整型int,如果需要不同类型的数据就要用到 interface{}. 空接口 interface{} 对于描述起不到任何的作用(因为它不包含任何的method),但interface{}在需要存储任意类型的数值的时候相当有用,因为它可以存储任意类型的数值. 一个函数把interface{}作为参数,那么它可以接受任意类型的值作为参数:如果一个函数返回i

随机推荐