已知head指向一个带头结点的单词链表,链表中每个结点包含数据long和指向被解构结点的指针

已知head指向一个带头结点的单词链表,链表中每个结点包含数据long和指向被解构结点的指针。编写函数实现如图的逆置。

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

#define elemType long /*元素类型*/
#define elemPrintType "%ld\t" /*元素打印类型*/
#define status int
#define OVERFLOW -1
#define ERROR 0
#define OK 1

/* 单链表数据结构 */
typedef struct lNode {
elemType data;
struct lNode *next;
} lNode, *linkList;

/******************************** 以下为函数声明 ********************************/
void initList (linkList *L); /* 初始化 */
void destroyList (linkList L); /* 销毁 */
status listIsEmpty (linkList L); /* 判断单链表是否为空 */
int listLength (linkList L); /* 获取单链表长度 */
status listInsertNode (linkList L, int i, elemType e); /* 单链表指定位置插入新元素 */
status listPrint (linkList L); /* 输出链表 */
status listReverse (linkList L); /* 逆置链表 */
/******************************** 以上为函数声明 ********************************/

/* 初始化 */
/* 操作结果:构造一个空的单链表L */
void initList (linkList *L) {
*L = (linkList) malloc (sizeof (struct lNode)); /* 产生头节点,并使L指向此头节点 */
if(!*L) /* 内存分配失败 */
exit (OVERFLOW);
(*L)->next = NULL; /* 指针域为空 */
}

/* 销毁 */
/* 初始条件:单链表L已存在。操作结果:销毁单链表L */
void destroyList (linkList L) {
linkList p,q;

p = L->next; /* p指向第一个结点 */
while (p) { /* 没到表尾 */
q = p->next;
     free (p);
     p = q;
}
free (L);
}

/* 判断单链表是否为空 */
/* 初始条件:单链表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
status listIsEmpty (linkList L) {
return L->next == NULL;
}

/* 获取单链表长度 */
/* 初始条件:单链表L已存在。操作结果:返回L中数据元素个数 */
int listLength (linkList L) {
int i = 0;
linkList p = L->next; /* p指向第一个结点 */

while (p) { /* 没到表尾 */
     i++;
     p=p->next;
}

return i;
}

/* 单链表指定位置插入新元素 */
/* 操作结果:在带头结点的单链表L中第i个位置之前插入元素e */
status listInsertNode (linkList L, int i, elemType e) {
int j=0;
linkList p=L,s;

while (p && j<i-1) { /* 寻找第i-1个结点 */
p = p->next;
     j++;
}

if (!p || j>i-1) /* 插入位置不合理:i小于1或者大于表长 */
return ERROR;

/* 生成新结点,并插入L中 */
s = (linkList) malloc (sizeof (struct lNode));
s->data = e;
s->next = p->next;
p->next = s;

return OK;
}

/* 输出链表 */
status listPrint (linkList L) {
if (listIsEmpty (L)) {
puts ("链表为空!");
return OK;
}
linkList p = L->next; /* p指向第一个结点 */
while (p!=NULL) {
printf (elemPrintType,p->data);
p = p->next;
}
putchar ('\n');
return OK;
}

/* 逆置链表 */
/* 初始条件:单链表L已存在。操作结果:链表元素逆置 */
status listReverse (linkList L) {
linkList p, q;

if (listIsEmpty (L)||listLength (L)==1) /* 若L为空表或只有一个元素 */ 
        return ERROR;  

p = L->next->next; /* p指向第2个结点 */
L->next->next = NULL; /* 首结点置为尾结点 */

/* 自第2个结点起遍历链表,循环将当前结点插入到头结点之后以逆置链表 */
    while (p) {
        q = p->next; /* q指向p的后继结点 */ 
/* 将p插入到头结点之后 */
p->next = L->next;
L->next=p;
/* 访问下一结点 */
p = q;
    }
    return OK;
}

int main (void) {
linkList head;
elemType a=1,b=2,c=3,d=4;

/* 初始化链表 */
initList (&head);
/* 插入若干元素 */
listInsertNode (head, 1, a);
listInsertNode (head, 1, b);
listInsertNode (head, 1, c);
listInsertNode (head, 1, d);

puts ("原链表内容:");
listPrint (head); /* 逆置链表 */

listReverse (head); /* 逆置链表 */
puts ("逆置后链表内容:");
listPrint (head);

destroyList (head); /* 销毁 */

getch ();
return 0 ;
}

运行结果

温馨提示:内容为网友见解,仅供参考
第1个回答  2013-11-12
node* reverse(node * head) //如果不带返回值,参数要写成node ** head ,涉及到参数值传递和地址传递问题
{
node *tmp=NULL; //临时保存翻转后的链表
node *ptr=NULL; //指向剩下的没有翻转的链表
if(head == NULL)
return head;

tmp = head ; //处理链表末尾使之指向NULL
head=head->next;
if(tmp !=NULL)
{
tmp->next = NULL; //末尾
}
else
{
return head; //只有一个节点
}

while(head != NULL) //思想是从待翻转的链表中依次取一个节点,每次取一个都放在临时保存的链表的最前面
{
ptr = head->next; //保存head节点后面的节点的指针
head->next = tmp; //将head节点放在临时链表最前面
tmp = head; //临时链表头节点更新为head
head = ptr;
}
head = tmp;
return head;
}

以上是最好的方法,还有一种就是先遍历链表,把每个节点的指针存储在一个数组中,然后从数组最后开始,反过来重新构建链表,这样空间复杂度高,但是简单本回答被提问者采纳

已知head指向一个带头结点的单词链表,链表中每个结点包含数据long和指向...
操作结果:销毁单链表L *\/void destroyList (linkList L) {linkList p,q;p = L->next; \/* p指向第一个结点 *\/while (p) { \/* 没到表尾 *\/q = p->next;

C语言,编写程序。已知head指向一个带头结点的单向链表,链表中每个结 ...
= NULL){ptr = ptr->next;if (ptr->data > max){max = ptr->data;}}return max;}Node* getMax_Address(List head){if (head->next == NULL){printf("链表中没有节点.\\n");exit(-1);}Node *ptr = head->next;Node *max_address = ptr;while (ptr->next != NULL){ptr = ...

已知head指向一个带头结点的单向链表
链表你是非顺序存储结构。因为数据结构是数据对象+关系 所以它必须在每个节点中包含数据元素(数据域)和它的关系(即指针域)链表中的第一个元素就是它的第一个节点。为了方便链表的操作,这里引入了头结点和头指针 所谓头结点就是在第一个节点前的节点,它不存放数据,仅仅存放第一个节点的地址。而头...

在链表中的一个结点的数据域和指针域有什么关系的?
数据域,就是存放这个节点的数据,指针域,存放的是另一个节点的地址,比如说单链表,指针域存放的就是后一个节点的地址。因为链表的节点在逻辑上是连续的,但是每个节点的物理地址可能不连续,就需要用一个指针,指向下一个节点的地址,这样,才能在找到一个节点后,继续寻找下一个节点。

数据结构:设计一个算法将一个带头结点的单链表A分解成两个带头结点的...
VisitList(headPtrB);DestroyList(&headPtrA, &tailPtrA); \/* 销毁链表 *\/ DestroyList(&headPtrB, &tailPtrB);return 0;} static void CreateList(LinkList *headPtr, LinkList *tailPtr, char ch){ LinkList newPtr;if ((newPtr = (LinkList)malloc(sizeof(Lnode))) == NULL){ exit(...

设L为单链表(带头结点),其中每个结点由一个整数域 data和指针域next组...
(*head)->next = NULL;} \/\/创建链表 void CreateList(Node **head){ int i;printf("请输入要插入的数据(以0结束):\\n");scanf("%d", &i);while(i != 0){ InsertList(head, i);scanf("%d", &i);} } \/\/插入链表 void InsertList(Node **head, int key){ Node *p, *q, *...

对于一个具有n个结点的单链表,在已知的结点*p后插入一个新结点的时间...
n)。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) +指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。以“结点的序列”表示线性表称作线性链表(单链表),单链表是链式存取的结构。

编写一个程序,将字符串computer赋给一个字符数组,然后从第一个字母...
include <stdio.h> include <string.h> void main(int argc, char **argv){ char str[] = "computer";char *pstr;int i;pstr = str;for(i = 0; i < strlen(str); i += 2){ printf("%c", *(pstr + i));} printf("\\n");} ...

某带头结点的单链表的头指针为head,则判定该链表为非空的条件是?_百度...
判定该链表为非空的条件是:head->next!=null。带头节点的情况下,链表空时还会存在一个节点,所以head不为空,head->next为空 不带头节点的情况下,链表空时,没有任何节点,head指向null。无论是否有头结点,头指针始终指向链表的第一个结点。如果有头结点,头指针就指向头结点。头结点的作用是...

一个非空的带头结点head的循环单链表的尾结点为*P,则P满足?
设这个非空循环单链表的头指针是head,然后指针p指向尾结点 则p满足:p->next==head->next

相似回答