单链线性表的基本操作--创建,插入,删除,查看,打印

单链线性表的基本操作–创建,插入,删除,查看,打印

C语言:

#include<stdio.h>
#include<stdlib.h>         // 分配地址和删除地址函数的头文件  

#define OK 1               // 宏定义,作为返回值 
#define ERROR 0

typedef int Status;        // 如需要更改类型,在此处更改一次即可 
typedef int ElemType;

typedef struct LNode{
	ElemType data;
	struct LNode *next;
}LNode;

void CreateList_L(LNode **L, int length){
	// 参数为指针的指针,即指针的地址,再为指针指向的地址分配内存 
	// 逆位序输入 n 个元素的值,建立带表头结点的单链线性表 L 
	(*L) = (LNode *)malloc(sizeof(LNode));
	(*L)->next = NULL;
	for(int i = length;i > 0;i--){
		LNode *p;
		p = (LNode *)malloc(sizeof(LNode));
		scanf("%d", &p->data);
		p->next = (*L)->next;
		(*L)->next = p;
	}
}
Status ListInsert_L(LNode *L, int i, ElemType e){
	// 在带头结点的单链线性表 L 中的第 i 个位置之前插入元素 e
	LNode *p, *s;
	p = L;
	int j = 0;
	while(p && j < i-1){           // 寻找第 i-1 个结点 
		p = p->next;
		++j;
	}
	if(!p || j > i-1)              
		return ERROR; 
	s = (LNode *)malloc(sizeof(LNode));    // 给新结点分配内存 
	s->data = e;
	s->next = p->next;
	p->next = s;
	return OK;
} 
Status GetElem_L(LNode *L, int i, ElemType &e){
	// L 为带头结点的单链表的头指针
	// 当地 i 个元素存在时,其指赋值给 e 并返回 OK ,否则返回 ERROR 
	LNode *p;
	p = L->next;       // 从第一个结点开始 
	int j = 1;
	while(p && j < i){       // 寻找第 i 个元素 
		p = p->next;
		++j;
	}
	if(!p || j > i)         // 没有找到返回 ERROR 
		return ERROR;
	e = p->data;
	return OK;	
}  

void PrintList_L(LNode *L){
	LNode *p;
	p = L->next;
	if(!p)
		printf("The list is empty
");
	while(p){
		printf("%d  ", p->data);
		p = p->next;
	}
	printf("
");
} 
Status ListDelete_L(LNode *L, int i, ElemType &e){
	// 在带有头结点的单链线性表 L 中,删除第 i 个元素, 并由 e 返回其值
	LNode *p;
	p = L;
	int j = 0;
	while(!p && j < i-1){      // 寻找第 i-1 个元素 
		p = p->next;
		++j;
	}
	if(!p || j > i-1)
		return ERROR;
	LNode *q;
	q = p->next;	
	p->next = p->next->next;
	e = q->data;
	free(q);                  // 释放结点 
	return OK;
}

int main()
{
	LNode *head;
	ElemType result1, result2;
	int n;
	// 创建一个单链线性表 长度为 5
	printf("请输入列表长度: 
");
	scanf("%d", &n);
	CreateList_L(&head, n);
	printf("请向列表输入数值: 
");
	// 打印此时列表 
	PrintList_L(head); 
	
	// eg: 得到单链表第一个元素 
	GetElem_L(head, 1, result1);	
	printf("第一个元素是: %d
", result1);
	// 打印此时列表 
	PrintList_L(head); 
	
	// 向列表第一个元素前插入元素 99 
	ListInsert_L(head, 1, 99);
	// 打印此时列表 
	PrintList_L(head); 
	
	// 删除单链线性表第一个元素 
	ListDelete_L(head, 1, result2);
	printf("删除的元素是: %d
", result2);
	// 打印此时列表 
	PrintList_L(head); 
	
	return 0;	
}

关键点:

void CreateList_L(LNode **L, int length);

用到了二次指针,指针的指针,即指针的地址。如果只是 LNode *L 的话,系统并不知道 L 指向的什么,会报错。传递LNode **L(指针的地址),再对指向列表的指针操作即可。

CreateList_L(&head, n);

调用该函数时参数自然是是指针的地址。

以下是用java语言实现上述的功能:

import java.util.Scanner;

public class MyLinkList {
	static int getdata, deldata;           // 用于存储返回数值和删除数值
	static Scanner sc = new Scanner(System.in);
	static Node head;
	private static class Node{             // MyLinkiList 类嵌套 Node 类(结点类)
		Node(int data){                   
			this.data = data;              // this 来区分局部变量和全局变量
			next = null;
		}
		Node(){                            // 构造方法的重载
			this.data = 0;
			next = null;
		}
		public int data;
		public Node next;
	}
	
	public static void createList(int length) {
		// 逆位序输入 sc.nextInt()个元素的值,建立带表头结点的单链线性表 L 
		head = new Node();                   // 头结点
		for(int i = length;i > 0;i--) {
			Node p = new Node(sc.nextInt());
			p.next = head.next;
			head.next = p;
		}
	}
	
	public static boolean listInsert(int i, int data) {
		// 单链线性表 L 中的第 i 个位置之前插入元素 e
		int j = 0;
		Node p = head;
		while(p != null && j < i-1) {      // 寻找第 i-1 个结点 
			p = p.next;
			++j;
		}
		if(p == null || j > i-1)          // 没有找到
			return false;
		Node q = new Node(data);          // 新结点
		q.next = p.next;
		p.next = q;
		return true;
	}
	
	public static boolean getElem(int i) {
		// 当地 i 个元素存在时,其指赋值给 getdata 并返回 true ,否则返回 false
		int j = 0;
		Node p = head;
		while(p != null && j < i) {      // 寻找第 i 个元素 
			p = p.next;
			++j;
		}
		if(p == null || j > i)           // 没有找到
			return false;
		getdata = p.data;
		return true;
	}
	
	public static void printList() {
		Node p = head.next;
		if(p == null)
			System.out.println("The list is empty");
		while(p != null) {
			System.out.print(p.data + "  ");
			p = p.next;
		}
		System.out.println();
	}
	
	public static boolean listDelete(int i) { 
		// 删除第 i 个元素, 并由 deldata 返回其值
		Node p = head;
		int j = 0;
		while(p != null && j < i-1) {      // 寻找第 i-1 个元素 
			p = p.next;
			++j;
		}
		if(p == null || j > i-1)           // 没有找到
			return false;
		deldata = p.next.data;
		p.next = p.next.next;
		return true;
	}
	
	public static void main(String [] args) {
		System.out.println("请输入列表长度: ");
		// 创建一个单链线性表 长度为 n
		int n = sc.nextInt();
		System.out.println("请向列表输入数值: ");
		createList(n);
		System.out.print("创建后的列表是: "); 
		printList(); 
		
		// 查看单链表第一个元素 
		if(getElem(1))	
			System.out.println("第一个元素是: " + getdata);
		
		// 向列表第一个元素前插入元素 99 
		if(listInsert(1, 99)) {
			System.out.print("插入后的列表: ");
			printList(); 
		}
		
		// 删除单链线性表第一个元素 
		if(listDelete(1))
			System.out.println("删除的元素是: " + deldata);
		System.out.print("删除后的列表: ");
		printList(); 
	}
}

关键点:

private static class Node

Node作为MyLinkList类的内部类,可以说是MyLinkList的内部私有成员。

Java语言利用面向对象的优势,避免使用难以理解指针。有对象就是好!

小编初学,望多指教。

原文地址:https://www.cnblogs.com/jiaohuadehulike/p/14295026.html